java word转pdf linux_java实现word转pdf在线预览(前端使用PDF.js;后端使用openoffice、aspose)...
背景
之前一直是用户点击下载word文件到本地,然后使用office或者wps打开。需求优化,要实现可以直接在线预览,无需下载到本地然后再打开。
随后开始上网找资料,网上资料一大堆,方案也各有不同,大概有这么几种方案:
1.word转html然后转pdf
2.Openoffice + swftools + Flexmapper + jodconverter
3.kkFileView
分析之后最后决定使用Openoffice+PDF.js方式实现
环境搭建
1.安装Openoffice,下载地址:http://www.openoffice.org/download/index.html
安装完成之后,cmd进入安装目录执行命令:soffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -nologo -headless -nofirststartwizard
2.PDF.js,下载地址:http://mozilla.github.io/pdf.js/
下载之后解压,目录结构如下:
代码实现
编码方面,分前端后:
后端:java后端使用openoffice把word文档转换成pdf文件,返回流
前端:把PDF.js解压后的文件加到项目中,修改对应路径,PDF.js拿到后端返回的流直接展示
后端
项目使用springboot,pom文件添加依赖
com.artofsolving
jodconverter
2.2.1
org.openoffice
jurt
3.0.1
org.openoffice
ridl
3.0.1
org.openoffice
juh
3.0.1
org.openoffice
unoil
3.0.1
application.properties配置openoffice服务地址与端口
openoffice.host=127.0.0.1
openoffice.port=8100
doc文件转pdf文件
importjava.io.BufferedInputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.OutputStream;importjava.net.ConnectException;importjavax.servlet.http.HttpServletResponse;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importcom.xxx.utils.Doc2PdfUtil;
@Controller
@RequestMapping("/doc2PdfController")public classDoc2PdfController {
@Value("${openoffice.host}")privateString OpenOfficeHost;
@Value("${openoffice.port}")privateInteger OpenOfficePort;private Logger logger = LoggerFactory.getLogger(Doc2PdfController.class);
@RequestMapping("/doc2pdf")public voiddoc2pdf(String fileName,HttpServletResponse response){
File pdfFile= null;
OutputStream outputStream= null;
BufferedInputStream bufferedInputStream= null;
Doc2PdfUtil doc2PdfUtil= newDoc2PdfUtil(OpenOfficeHost, OpenOfficePort);try{//doc转pdf,返回pdf文件
pdfFile =doc2PdfUtil.doc2Pdf(fileName);
outputStream=response.getOutputStream();
response.setContentType("application/pdf;charset=UTF-8");
bufferedInputStream= new BufferedInputStream(newFileInputStream(pdfFile));byte buffBytes[] = new byte[1024];
outputStream=response.getOutputStream();int read = 0;while ((read = bufferedInputStream.read(buffBytes)) != -1) {
outputStream.write(buffBytes,0, read);
}
}catch(ConnectException e) {
logger.info("****调用Doc2PdfUtil doc转pdf失败****");
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally{if(outputStream != null){try{
outputStream.flush();
outputStream.close();
}catch(IOException e) {
e.printStackTrace();
}
}if(bufferedInputStream != null){try{
bufferedInputStream.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
}
importjava.io.File;importjava.net.ConnectException;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importcom.artofsolving.jodconverter.DocumentConverter;importcom.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;importcom.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;importcom.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;public classDoc2PdfUtil {private String OpenOfficeHost; //openOffice服务地址
private Integer OpenOfficePort; //openOffice服务端口
publicDoc2PdfUtil(){
}publicDoc2PdfUtil(String OpenOfficeHost, Integer OpenOfficePort){this.OpenOfficeHost =OpenOfficeHost;this.OpenOfficePort =OpenOfficePort;
}private Logger logger = LoggerFactory.getLogger(Doc2PdfUtil.class);/*** doc转pdf
*@returnpdf文件路径
*@throwsConnectException*/
public File doc2Pdf(String fileName) throwsConnectException{
File docFile= new File(fileName + ".doc");
File pdfFile= new File(fileName + ".pdf");if(docFile.exists()) {if (!pdfFile.exists()) {
OpenOfficeConnection connection= newSocketOpenOfficeConnection(OpenOfficeHost, OpenOfficePort);try{
connection.connect();
DocumentConverter converter= newStreamOpenOfficeDocumentConverter(connection);//最核心的操作,doc转pdf
converter.convert(docFile, pdfFile);
connection.disconnect();
logger.info("****pdf转换成功,PDF输出:" + pdfFile.getPath() + "****");
}catch(java.net.ConnectException e) {
logger.info("****pdf转换异常,openoffice服务未启动!****");
e.printStackTrace();throwe;
}catch(com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) {
System.out.println("****pdf转换器异常,读取转换文件失败****");
e.printStackTrace();throwe;
}catch(Exception e) {
e.printStackTrace();throwe;
}
}
}else{
logger.info("****pdf转换异常,需要转换的doc文档不存在,无法转换****");
}returnpdfFile;
}
}
前端
把pdfjs-2.0.943-dist下的两个文件夹build、web整体加到项目中,然后把viewer.html改成viewer.jsp,并调整了位置,去掉了默认的pdf文件compressed.tracemonkey-pldi-09.pdf,将来使用我们生成的文件
viewer.jsp、viewer.js注意点:
1.引用的js、css路径要修改过来
2.viewer.jsp中调用pdf/web/viewer.js,viewer.js中配置了默认的pdf文件路径,我们要动态生成pdf,因此需要修改,在jsp中定义一个参数DEFAULT_URL,然后在js中使用它
3.jsp中写了一个ajax获取pdf流,之后赋值给DEFAULT_URL,然后再让viewer.js去加载,因此需要把/pdf/web/viewer.js放到ajax方法后面
4.viewer.js中把compressed.tracemonkey-pldi-09.pdf改成我们定义的变量DEFAULT_URL;pdf.worker.js的路径修改成对应路径
varqtpath= '${qtpath}';varfileName= '${fileName}';
PDF.js viewer
varDEFAULT_URL= "";//注意,删除的变量在这里重新定义
varPDFData= "";
$.ajax({
type:"post",
async:false,//mimeType:'text/plain; charset=x-user-defined',
url:'${qtpath}/doc2PdfController/doc2pdf',
data:{'fileName':fileName},
success:function(data){
PDFData=data;
}
});varrawLength=PDFData.length;//转换成pdf.js能直接解析的Uint8Array类型,见pdf.js-4068
vararray= newUint8Array(newArrayBuffer(rawLength));for(i= 0; i
array[i]=PDFData.charCodeAt(i)& 0xff;
}
DEFAULT_URL=array;
...
效果
分割线
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
本以为完美的实现了doc在线预览,上测试环境后发现了一个大坑,我们的doc文件不是在本地office创建后上传的,是其他同事用freemarker ftl模板生成的,这种生成的doc文件根本不是微软标准的doc,本质是xml数据结构,openoffice拿这种文件去转换pdf文件直接就报错了
上网查资料查了半天也没找到这种问题的解决方案,想想只能是放弃openoffice改用其他方法了(freemarker ftl生成doc这个肯定是不能动的)
看到一些博客使用word--html--pdf生成pdf,还有的使用freemarker ftl xml 生成pdf感觉还是太繁琐了,我只是想拿现有的doc(虽然是freemarker ftl生成的)转换成pdf啊
继续看博客查资料,看到一种方法,使用aspose把doc转换成pdf,抱着试一试的心态在本地测试了下,没想到竟然成了,感觉太意外了,aspose方法超级简单,只要导入jar包,几行代码就可以搞定,并且转换速度比openoffice要快很多。很是奇怪,这么好用这么简单的工具为什么没在我一开始搜索word转pdf的时候就出现呢
aspose doc转pdf
在maven仓库搜索aspose,然后把依赖加入pom.xml发现jar包下载不下来,没办法,最后在csdn下载aspose jar包,然后mvn deploy到仓库
pom.xml
com.aspose.words
aspose-words-jdk16
14.9.0
importjava.io.BufferedInputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.OutputStream;importjava.net.ConnectException;importjavax.servlet.http.HttpServletResponse;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importcom.xxx.utils.Doc2PdfUtil;
@Controller
@RequestMapping("/doc2PdfController")public classDoc2PdfController {private Logger logger = LoggerFactory.getLogger(Doc2PdfController.class);
@RequestMapping("/doc2pdf")public voiddoc2pdf(String fileName,HttpServletResponse response){
File pdfFile= null;
OutputStream outputStream= null;
BufferedInputStream bufferedInputStream= null;
String docPath= fileName + ".doc";
String pdfPath= fileName + ".pdf";try{
pdfFile=Doc2PdfUtil.doc2Pdf(docPath, pdfPath);
outputStream=response.getOutputStream();
response.setContentType("application/pdf;charset=UTF-8");
bufferedInputStream= new BufferedInputStream(newFileInputStream(pdfFile));byte buffBytes[] = new byte[1024];
outputStream=response.getOutputStream();int read = 0;while ((read = bufferedInputStream.read(buffBytes)) != -1) {
outputStream.write(buffBytes,0, read);
}
}catch(ConnectException e) {
logger.info("****调用Doc2PdfUtil doc转pdf失败****");
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally{if(outputStream != null){try{
outputStream.flush();
outputStream.close();
}catch(IOException e) {
e.printStackTrace();
}
}if(bufferedInputStream != null){try{
bufferedInputStream.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
}
Doc2PdfUtil.java
importjava.io.ByteArrayInputStream;importjava.io.File;importjava.io.FileOutputStream;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importcom.aspose.words.License;importcom.aspose.words.SaveFormat;public classDoc2PdfUtil {private static Logger logger = LoggerFactory.getLogger(Doc2PdfUtil.class);/*** doc转pdf
*@paramdocPath doc文件路径,包含.doc
*@parampdfPath pdf文件路径,包含.pdf
*@return
*/
public staticFile doc2Pdf(String docPath, String pdfPath){
File pdfFile= newFile(pdfPath);try{
String s= "Aspose.Total for JavaAspose.Words for JavaEnterprise20991231209912318bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=";
ByteArrayInputStream is= newByteArrayInputStream(s.getBytes());
License license= newLicense();
license.setLicense(is);
com.aspose.words.Document document= newcom.aspose.words.Document(docPath);
document.save(newFileOutputStream(pdfFile),SaveFormat.PDF);
}catch(Exception e) {
logger.info("****aspose doc转pdf异常");
e.printStackTrace();
}returnpdfFile;
}
}
aspose-words-jdk16-14.9.0.jar下载地址
https://download.csdn.net/download/u013279345/10868189
window下正常,linux下乱码的解决方案
使用com.aspose.words将word模板转为PDF文件时,在开发平台window下转换没有问题,中文也不会出现乱码。但是将服务部署在正式服务器(Linux)上,转换出来的PDF中文就出现了乱码。在网上找了很久,才找到原因,现将解决办法分享给大家。
一、问题原因分析
在window下没有问题但是在linux下有问题,就说明不是代码或者输入输出流编码的问题,根本原因是两个平台环境的问题。出现乱码说明linux环境中没有相应的字体以供使用,所以就会导致乱码的出现。将转换无问题的windos主机中的字体拷贝到linux平台下进行安装,重启服务器后转换就不会出现乱码了。
二、window字体复制到linux环境并安装
按照教程安装完成后重启linux服务器即可搞定乱码问题。
1. From Windows
Windows下字体库的位置为C:\Windows\fonts,这里面包含所有windows下可用的字体。
2. To Linux
linux的字体库是 /usr/share/Fonts 。
在该目录下新建一个目录,比如目录名叫 windows(根据个人的喜好,自己理解就行,当然这里是有权限要求的,你可以用sudo来执行)。
然后将 windows 字体库中你要的字体文件复制到新建的目录下(只需要复制*.ttc,和*.ttf的文件).
复制所有字体:
sudo cp *.ttc /usr/share/fonts/windows/
sudo cp *.ttf /usr/share/fonts/windows/
更改这些字体库的权限:
sudo chmod 755 /usr/share/fonts/windows/*
然后进入Linux字体库:
cd /usr/share/fonts/windows/
接着根据当前目录下的字体建立scale文件
sudo mkfontscale
接着建立dir文件
sudo mkfontdir
然后运行
sudo fc-cache
重启 Linux 操作系统就可以使用这些字体了。
linux下乱码问题解决方案转载自:
https://blog.csdn.net/hanchuang213/article/details/64905214
https://blog.csdn.net/shanelooli/article/details/7212812
java word转pdf linux_java实现word转pdf在线预览(前端使用PDF.js;后端使用openoffice、aspose)...相关推荐
- java实现在线预览txt转pdf
java实现在线预览txt转pdf 首先引入itext的jar包 <dependency><groupId>com.itextpdf</groupId><ar ...
- 前端实现pdf,word,doc等Office文档格式在线预览
在做一些后台管理或者h5页面的时候 通常会遇到Office文档格式的在线预览功能.虽然看似简单,里面却隐藏着很大的坑.简单是因为现在有各种插件可以下载实现,坑是因为涉及到一些兼容性和安全性等各种千奇百 ...
- Word,Excel,PPT等Office文件Web浏览器在线预览
博主联系方式 https://fizzz.blog.csdn.net/article/details/113049879 前两天接到一个需求:需要在线预览用户上传的Word,Excel,PPT文档 ...
- java文件预览_java 在线预览doc,pdf
先说一说如何实现在线预览doc网上查了很多资料,基本思路就是将doc 转为 pdf,由于低版本浏览器不支持预览pdf,所以基本是再将pdf 转为 swf. 由于我这次做的需求只需要兼容chrome即可 ...
- java 文件在线预览_java 在线预览doc,pdf
先说一说如何实现在线预览doc 网上查了很多资料,基本思路就是将 doc 转为 pdf,由于低版本浏览器不支持预览 pdf,所以基本是再将 pdf 转为 swf (使用FlexPaper + swft ...
- OFD文件、pdf文件相互转换、ofd文件在线预览
文章目录 一.在线预览 1. api使用 2. 案例 3. 效果 二.ofd转odf 2.1. api使用 2.2. 参考案例 三.odf转ofd 3.1. api使用 3.2. 参考案例 3.3. ...
- 实现pdf文件在线预览(需要PDF文件的路径)
工作中需要完成一个PDF在线预览的功能,最简单的方法还是使用pdf的插件. 1.首先下载插件 链接:https://pan.baidu.com/s/1q4zuHrmjJL9QSEn2Iy5O9Q 提取 ...
- jsp 展示服务器pdf文件,pdf在线预览_jsp实现pdf在线预览功能
摘要 腾兴网为您分享:jsp实现pdf在线预览功能,钻石星球,桌面时钟,学堂在线,新东方等软件知识,以及新游手柄游戏厅,qq6.2,硬盘坏道,录音盒,番茄花园rom,x架子,内蒙古科协,陕西交管121 ...
- web浏览器在线预览Excel,PDF,world文档解决方案
众所周知啊,在web浏览器中是无法直接预览Excel.world文档等文件的,PDF有的浏览器是打开预览,有的浏览器是跳转到下载页,行为不一致也是让开发者头疼的事情. 今天给大家提供一个解决方案,实现 ...
- 在线编辑PDF:GcPDF|PDF在线预览GrapeCity Documen PDF
GrapeCity Documents for PDF (简称:GcPDF)是一款服务端 PDF 组件,支持 .NET 和 .NET Core,无需 Adobe Acrobat 依赖 ,即可超快批量生 ...
最新文章
- SAP MM 明明已经扩展供应商到采购组织下,采购订单里还是报错?
- semantic ui框架学习笔记三
- 你了解微服务架构么?
- linux信号掩码线程,20.10 信号掩码(阻塞信号传递)
- 使用 AngularJS 和 ReactJS 的经验
- leetcode 740. Delete and Earn | 740. 删除并获得点数(暴力递归->傻缓存->DP)
- 复制:王垠:数学和编程
- 搞定使用MySQL导入外部的SQL文件执行
- 稚晖君软件硬件开发环境总结
- 每月一书(202101):《财富自由之路》-李笑来
- c语言怎么用setw输出每行6个,setw和setfill控制输出间隔
- CNI IPAM插件分析 --- 以hostlocal为示例
- 疯狂java笔记(七) - Java集合之Map
- circos 中堆积柱状图的画法
- android+后台自动更新+上架,Android增量自动更新
- CSS实现图片无限循环无缝滚动
- python迭代器和生成器
- (10.2)【隐写实现】简介、流程图、具体步骤
- 13.4.2 查询某列数据的总和
- 中国储能行业市场“十四五”规划分析与未来战略建议报告2022-2028年版
热门文章
- h5(HBuilderX+mui)开发App
- 关于Mysql1251解决办法
- Android 如何检测网速,例如在10秒内告诉我网速是好是坏?
- 最新版MySQL 8.0 的下载与安装(详细教程)
- springboot+dubbo+zookeeper怎么设置熔断器并调用
- linux redis集群搭建
- 自以为了不起的人一文不值!
- sogou拼音装不上
- linux java amr转mp3,微信语音Linux-centos下ffmpeg安装如何amr转mp3播放
- windows utf8 签名 一个很二的问题(经典乱码“锘”字)