背景

之前一直是用户点击下载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在线预览_java实现word转pdf在线预览(前端使用PDF.js;后端使用openoffice、aspose)...相关推荐

  1. java word文档生成_java生成word文档

    java生成word文档有多种方式: 1:Jacob是Java-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁.使用Jacob自带的DLL动态链接库,并通过JNI的方式实现 ...

  2. java全文检索word中的内容_java获取word里面的文本

    需求场景 开发的web办公系统如果需要处理大量的Word文档(比如有成千上万个文档),用户一定提出查找包含某些关键字的文档的需求,这就要求能够读取 word 中的文字内容,而忽略其中的文字样式.表格. ...

  3. java返回浏览器预览PDF_如何实现springmvc将返回的给前端的pdf文件放在浏览器里预览?...

    想在浏览器里直接GET目标URL,然后就把PDF在浏览器里预览出来(不用前端插件的前提下),就像这样: http://docs.spring.io/spring/- 后端代码: @RequestMap ...

  4. java word在线预览_java 生成word文档并且在线预览的问题

    富文本? 用iText或者PD4ML直接转换为pdf [code="java"] String outputFile = "D:/Test/demo_3.pdf" ...

  5. java实现doc内容对比_Java平台Word格式处理控件Spire.Doc8月新功能代码演示:比较两个 Word 文档的内容...

    Spire.Doc 能够非常完美的识别中文字符并支持丰富的word文档元素:文本框.页眉.页脚.项目符号和编号.表格.文本.超链接.水印.图片.形状等. 自版本3.8.8开始,Spire.Doc fo ...

  6. java 操作 word 表格和样式_java 处理word文档 (含图片,表格内容)

    因为本人长期从事Oa相关项目的开发,所以处理word文档,Pdf,Excel等是在所难免的. 1.需求      处理Excel 能够用jxl        或者poi 2需求     用户在系统上填 ...

  7. java提取word中的文字_Java 提取Word中的文本和图片

    本文将介绍通过Java来提取或读取Word文档中文本和图片的方法.这里提取文本和图片包括同时提取文档正文当中以及页眉.页脚中的的文本和图片. 使用工具:Free Spire.Doc for Java ...

  8. java word 文档合并_Java 合并Word文档

    概述 合并文档可以是将两个包含一定逻辑关系的文档合并成一个完整的文档,也可以是出于方便文档存储.管理的目的合并多个文档为一个文档.下面,就将以上文档操作需求,通过Java程序来实现Word文档合并.合 ...

  9. java导出word文档组件_java导出word文档(转)

    导出word文档有两种方式:第一种是使用POI,第二种是使用itext组件,下面逐渐介绍: 1.使用POI的方式:本方式目前没法改变字体样式,只能输出纯文本. /** * 试卷导出word文档 * @ ...

最新文章

  1. 易买网的一些增删改查
  2. 如何为回归问题选择最合适的机器学习方法?
  3. IOT数据库选型——NOSQL,MemSQL,cassandra,Riak或者OpenTSDB,InfluxDB
  4. PAT A 1118. Birds in Forest (25)【并查集】
  5. ​esquisse: 快速可视化图形的 Rstudio 插件
  6. 解决vue addRoutes多次添加路由重复问题。
  7. python--时间日期
  8. centos下安装php-fpm,centos下怎么安装php-fpm
  9. 计算机网络实验一:网线制作和局域网组建lab1 report
  10. 飞猪研报:知识xingqiu
  11. C++面向对象程序设计
  12. Mac 下配置使用windows局域网共享打印机
  13. R3.6.3下载 Rstudio下载及安装,网盘链接永久有效
  14. 计算机开根号原理,根号的原理_怎么开的根号,有原理吗
  15. CentOS Stream 8 安装Oracle 19C (静默模式)
  16. CTFHub 工控组态分析 WP
  17. flask-sqlachemy note
  18. 07宝来经典车机CD收音机(RC668)改装增加蓝牙播放音乐
  19. 【算法无用系列】字符串匹配那些事——BM算法
  20. 输电线路山火在线监测系统

热门文章

  1. 冗余-安全设计的基石
  2. iOS拨打电话的三种方法
  3. 总结:计算机中字符串比较大小的规则
  4. 谁说了真话,谁打碎了花瓶
  5. Unity3D实战【八】Animator 动画控制器
  6. kali 移动文件命令
  7. z370对应的服务器芯片,Z370芯片组为何仅支持第八代酷睿处理器?供电针脚不一样...
  8. 逆向分析_VB6.0制作登录界面
  9. SOT23-6 大功率升压IC 5V/1A典型应用
  10. Jenkins代码审查