pdf预览功能 java_PDF/Excel文件预览功能完整实现-java版本

新需求

最近接到一个新的需求,说是之前直接下载的PDF文件或者是Excel文件,现在不能直接下载,需要实现在线预览功能。

前端人员拿到这个需求后,去看了一下以前的代码,以前调用的下载接口和PDF文件预览接口都是直接将文件成二进制

流的形式,然后响应到前端。有的接口即使是动态生成PDF文件或者是Excel文件都是同样的操作,也是将动态生成的对

象的二进制流写入到响应对象中。前端人员遇到的问题是,如果直接将二进制流返回给前端,前端调用的时候,会直接

载而不能做其他处理。然后找我协商,看看后端人员有没有好的解决办法,我去百度里面查找,找到一个靠谱的方法,

大致意思就是将文件转为Base64格式的字符串数据,然后返回给前端,前端在去做响应的处理。

解决方案

确定方案后,然后我继续去百度里面查找如何将文件转为Base64格式的数据,找到一个可行的方法,网址如下:

https://blog.csdn.net/dbeautifullife/article/details/77650713

使用里面的方法写成了一个工具类,然后在根据业务的需要,添加了动态生成PDF文件和动态生成Excel

文件的方法,很好的解决了文件转换为Base64的方式。

import lombok.extern.slf4j.Slf4j;

import org.apache.poi.ss.usermodel.Workbook;

import org.springframework.context.annotation.Scope;

import sun.misc.BASE64Encoder;

import java.io.*;

/**

* @Description: 文件转 base64 工具类

* @ClassName: ToBase64Utils

* @author: dengchao

* @date: 2020/11/24 9:27

*/

@Slf4j

@Scope(value = "singleton")//单例

public class ToBase64Utils {

//私有化构造方法

private ToBase64Utils(){}

/* @Description: ava 自带的转换base64对象

* @author: dengchao

* @date: 2020-10-24 10:10

*/

private final static BASE64Encoder encoder = new BASE64Encoder();

/* @Description: 读取实体文件转 Base64

* @author: dengchao

* @date: 2020/11/24 9:29

* @param: file 文件对象

* @return: String 字符串

*/

public static String PDFToBase64(File file) {

if(file == null || !file.exists()){

throw new BaseException(MessageConstant.A000001, "传入的file对象为null或者文件不存在");

}

if(file.isDirectory()){

throw new BaseException(MessageConstant.A000001, "传入的file对象是一个路径,不是具体的文件");

}

ToBase64Utils.log.error("PDFToBase64-开始读取文件!");

try ( FileInputStream fin = new FileInputStream(file);

BufferedInputStream bin = new BufferedInputStream(fin);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

BufferedOutputStream bout = new BufferedOutputStream(baos);

){

byte[] buffer = new byte[1024];

int len = bin.read(buffer);

while(len != -1){

bout.write(buffer, 0, len);

len = bin.read(buffer);

}

//刷新此输出流并强制写出所有缓冲的输出字节

bout.flush();

return ToBase64Utils.byteArrayToBase64(baos);

} catch (FileNotFoundException e) {

ToBase64Utils.log.error("PDFToBase64-文件未找到!");

e.printStackTrace();

} catch (IOException e) {

ToBase64Utils.log.error("PDFToBase64-读取文件异常!");

e.printStackTrace();

}

return "";

}

/* @Description: 动态生成 Excel对象 转 Base64

* @author: dengchao

* @date: 2020/11/24 9:37

* @param: No such property: code for class: Script1

* @return:

*/

public static String workToBase64(Workbook workbook){

if(workbook == null){

throw new BaseException(MessageConstant.A000001, "传入Excel文件对象错误");

}

String excelBase64 = "";

try(ByteArrayOutputStream bos = new ByteArrayOutputStream()){

workbook.write(bos);

bos.flush();

excelBase64 = ToBase64Utils.byteArrayToBase64(bos);

}catch(Exception e){

excelBase64 = "";

ToBase64Utils.log.error("EXCEL文件转Base64错误!", e);

}

return excelBase64;

}

/* @Description: 字节输出流转 Base64

* @author: dengchao

* @date: 2020/11/24 9:48

* @param: No such property: code for class: Script1

* @return:

*/

public static String byteArrayToBase64(ByteArrayOutputStream bos){

if(bos == null){

throw new BaseException(MessageConstant.A000001, "传入的字节输入流对象错误");

}else{

byte[] byteArray = bos.toByteArray();

String resultString = ToBase64Utils.encoder.encodeBuffer(byteArray).trim();

return resultString;

}

}

}

核心原理就是将二进制的输出流转换为Base64字符串即可。

实际操作

工具类写好之后,立马和前端人员进行调试,测试通过,能够正常返回Base64的字符串,并且前端人员拿到数据后,可以进一步做其他操作。

前端人员的代码能看懂一大半,使用的VUE组件。大致意思就是引用VUE组件生成一个excel文件对象,然后在动态的拼接数据,最后显示

在页面中。

const workbook = await XLSX.read(res.responseBody, { type: 'base64', cellDates: true })

workbook.SheetNames.map(async item => {

if (item) {

const title = item

let html = await XLSX.utils.sheet_to_html(workbook.Sheets[item]).match(/

const totalTr = html.match(//g).length

const totalEmptyTd = html.match(/

/g).length

// 如果每行结尾都是空 td,则过滤掉

if (totalTr === totalEmptyTd) {

html = html.replace(/

/g, '')

}

this.xlsxHtml.push({title, html})

}

})

最终完成这个功能,PDF也是同样的处理方式。对于一般人来说,这完全能够满足需求,实现在线预览的功能,而且效果也很好。

可是对于专业人士来说,这种操作方式还是存在问题的,只要拿到文件的Base64的字符串数据,就可以拿到整个文件的所有数

据。所以对于安全要求比较严格的业务来说,这个是不达标的。不过对于我们来说,已经满足要求了。

你可能感兴趣的:(pdf预览功能,java)