大致思路
接到一个需求,将vue页面生成word,并且也可以生成pdf
前端VUE生成WORD
因为使用的是VUE大致也是分为两种方法
- jquery的wordExport插件(这里使用VUE不建议使用jquery不详细阐述想研究可以自己去试一下)
- 大佬自己改造的js-export-word插件,和jQuery的wordExport效果差不多但是感觉还是比较好用的,而且给大佬提issue也是很快就回复了GitHub - huangbohang/export-word: 一个html导出为word的JS库
具体实现
导入方法
//导入方法
npm install -D js-export-word
页面引用(这里我修改了库里面的方法方便导出pdf)
import exportWord from 'js-export-word'
const wrap = document.getElementById('test')
const config = {
addStyle:true, // 是否导出样式,默认为true,此操作会将所有样式转换成行内样式导出
fileName:'测试文件', // 导出文件名
toImg:['.need-to-img','.bg-danger'], // 页面哪些部分需要转化成图片,例如echart图表之类
success(){} // 完成之后回调,一般页面篇幅比较大,时间比较长
}
exportWord(wrap,config,'word') //这里进行了改造因为要修改里面的方法将word文件流提交到后台
修改JS方法
async function exportWord(dom, config,type ){
const installApp = new App(dom, config)
await installApp.init()
if (type=='word'){
installApp.exportWord()
} else {
installApp.exportPdf()
}
}
添加导出PDF方法
//导出pdf
exportPdf(){
var blob = wordexport(this.c_dom);
var formData = new FormData();
formData.append("file",blob,"blob.doc");
var fileName =this.config.fileName;
send(formData,fileName);
function send(formData,fileName) {
axios
.post(process.env.VUE_APP_BASE_API + "/common/upload/Word2Pdf", formData,{responseType: "arraybuffer",Authorization: "Bearer " + getToken() })
.then(function(res) {
const link = document.createElement('a')
let blob = new Blob([res.data], {type: 'application/pdf;chartset=UTF-8'})
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
// 文件名称,可自定义,也可以从后端获取
link.download = fileName+".pdf"
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
})
.catch(function(error) {
console.log(error);
});
}
}
后端转换PDF
在网上找到多种方式
1、documents4j(依赖于windows系统和office)
2、expire(免费的版本只能转换3页)
3、aspose(是付费的但是网上有License,还是比较方便的)
4、itextpdf(转换之后的pdf格式混乱,字体混乱,也没有深入研究)
最后也是看到了大佬的博客docx文件转pdf,使用aspose words 转pdf,并且解决表格格式错乱_Mr_going的博客-CSDN博客_aspose docx转pdf
参照这个博客完成了转换,只有分页换行的时候有几行换页了,但是样式没有混乱比较符合。
这里也是大致整理一下整体流程(有部分是贴的大佬的博客)
具体实现
导入工具包的过程参照大佬的博客吧,我就写一下控制层接口的处理
需要修改工具包让工具返回FileOutputStream类型的值
@PostMapping("/common/upload/Word2Pdf")
public void Word2Pdf(MultipartFile file,HttpServletResponse response) {
File inputWord = null;
try {
//创建临时输入文件doc
inputWord=File.createTempFile("tmp.doc", null);
file.transferTo(inputWord);
inputWord.deleteOnExit();
InputStream docxInputStream = new FileInputStream(inputWord);
//创建临时输出文件pdf
File outf1 = File.createTempFile("temp-file-name", ".tmp");
outf1.deleteOnExit();
//转换PDF
FileOutputStream os = WordToPdfUtil.docxToPdf(docxInputStream,outf1);
// 返回文件流
response.setContentType("multipart/form-data");
//为文件重新设置名字,采用数据库内存储的文件名称
response.addHeader("Content-Disposition", "attachment; filename=\"" + "cs.pdf" + "\"");
//读取文件流并转化
FileInputStream ips = null;
ServletOutputStream out = null;
ips = new FileInputStream(outf1);
out = response.getOutputStream();
int len = 0;
byte[] buffer = new byte[1024 * 10];
while ((len = ips.read(buffer)) != -1){
out.write(buffer,0,len);
}
//写入
out.flush();
try {
out.close();
ips.close();
} catch (IOException e) {
System.out.println("关闭流出现异常");
e.printStackTrace();
}
return ;
} catch (Exception e) {
e.printStackTrace();
return ;
}
}
完成导出