赞
踩
文章迁移自语雀。
也许Java天生不适合处理Office文件吧,POI的使用一堆问题,现在SpringMVC+Spring+Mybatis的web项目想实现在线预览也是问题一大堆。马的,开始时打算使用OpenOffice+SWFTools+FlexPaper的,但是该方案是使用flash的,众所周知,flash明年就要死了,故放弃,后来又想使用pdf2HtmlEx将pdf转成html,这b办法也是一堆坑,摸索了半天,总算有了一个好的解决方案:
OpenOffice将Office文件转换为pdf,存储进服务器硬盘上的固定文件夹,随后将该文件夹在Tomcat中配置虚拟路径,Controller收到预览请求后查找到该虚拟路径返回,浏览器安装了Adobe acrobat之后就可以直接预览了。
Adobe acrobat的好处在哪里呢?在于它不仅支持pdf,对于txt,mp3,png,jpg,mp4等文件均可以直接预览,省去了很多事情。
当然,该方法也有局限,要求用户必须安装Adobe acrobat。
至于更好的办法目前还没有。
首先,给出OpenOffice4.0和jodconverter所需的jar包:
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.ConnectException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Scanner;
-
-
- import com.artofsolving.jodconverter.DocumentConverter;
- import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
- import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
- import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
-
- /**
- * Office文件转换工具
- * 将doc,docx,xls,xlsx,pp,pptx转换为pdf
- * @author shuaicenglou
- *
- */
- public class DocConverter {
- private String convert(InputStream fromFileInputStream, String toFilePath,String type) throws IOException {
- Date date = new Date();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
- String timesuffix = sdf.format(date);
- String docFileName = null;
- String htmFileName = null;
- if(".doc".equals(type)){
- docFileName = "doc_" + timesuffix + ".doc";
- htmFileName = "doc_" + timesuffix + ".pdf";
- }else if(".docx".equals(type)){
- docFileName = "docx_" + timesuffix + ".docx";
- htmFileName = "docx_" + timesuffix + ".pdf";
- }else if(".xls".equals(type)){
- docFileName = "xls_" + timesuffix + ".xls";
- htmFileName = "xls_" + timesuffix + ".pdf";
- }else if(".ppt".equals(type)){
- docFileName = "ppt_" + timesuffix + ".ppt";
- htmFileName = "ppt_" + timesuffix + ".pdf";
- }else if(".pptx".equals(type)){
- docFileName = "pptx_" + timesuffix + ".pptx";
- htmFileName = "pptx_" + timesuffix + ".pdf";
- }else{
- return null;
- }
- File htmlOutputFile = new File(toFilePath + File.separatorChar + htmFileName);
- File docInputFile = new File(toFilePath + File.separatorChar + docFileName);
- if (htmlOutputFile.exists()) {
- htmlOutputFile.delete();
- }
- htmlOutputFile.createNewFile();
- if (docInputFile.exists()) {
- docInputFile.delete();
- }
- docInputFile.createNewFile();
- /**
- * 由fromFileInputStream构建输入文件
- */
- try {
- OutputStream os = new FileOutputStream(docInputFile);
- int bytesRead = 0;
- byte[] buffer = new byte[1024 * 8];
- while ((bytesRead = fromFileInputStream.read(buffer)) != -1) {
- os.write(buffer, 0, bytesRead);
- }
-
- os.close();
- fromFileInputStream.close();
- } catch (IOException e) {
- }
-
- OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
- try {
- connection.connect();
- } catch (ConnectException e) {
- System.err.println("文件转换出错,请检查OpenOffice服务是否启动");
- }
- // convert
- DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
- converter.convert(docInputFile, htmlOutputFile);
- connection.disconnect();
- // 转换完之后删除word文件
- docInputFile.delete();
- return htmFileName;
- }
- /**
- * win下手动开启Openoffice服务
- * @param servicePath 服务安装位置
- */
- public static void startOpenOfficeService(String servicePath) {
- String command = servicePath + "program\\soffice -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard";
- try {
- Process pro = Runtime.getRuntime().exec(command);
- } catch (IOException e) {
- System.out.println("OpenOffice服务启动失败");
- }
- }
- /**
- * win下手动关闭OpenOffice服务
- */
- public static void shutdownOpenOfficeService() {
- try {
- Process pro = Runtime.getRuntime().exec("tasklist");
- Scanner in = new Scanner(pro.getInputStream());
- while(in.hasNext()) {
- String proString = in.nextLine();
- if(proString.contains("soffice.exe")) {
- String cmd = "taskkill /f /im soffice.exe";
- pro = Runtime.getRuntime().exec(cmd);
- System.out.println("soffice.exe关闭");
- }
- if(proString.contains("soffice.bin")) {
- String cmd = "taskkill /f /im soffice.bin";
- pro = Runtime.getRuntime().exec(cmd);
- System.out.println("soffice.bin关闭");
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 文件转换
- * @param inputPath 输入路径
- * @param outputPath 文件输出路径,文件名自动生成
- * @return
- */
- public boolean convert(String inputPath,String outputPath) {
- File file = new File(inputPath);
- String fileName = file.getName();
- boolean result = false;
- //判断文件后缀类型
- String type = "."+fileName.substring(fileName.lastIndexOf(".") + 1);
- try {
- FileInputStream fileInputStream = new FileInputStream(file);
- DocConverter d = new DocConverter();
- if(d.convert(fileInputStream, outputPath, type)!=null) {
- result = true;
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return result;
- }
- public static void main(String s[]) {
- new DocConverter().convert("D:\\a.xls", "D:\\");
- }
- }
上面代码生成的pdf存储在Tomcat配置的虚拟路径的文件夹里。
然后,Adobe acrobat自行下载安装即可
在这里要多说两句:
1.对于带有积分号等数学符号:MathType类型的doc,OpenOffice在转换时会丢失,导致文件不完整 ,这是OpenOffice自身的缺陷,目前无法避免
2.jdoconverter一定要使用2.2.2版本,否则docx,xlsx,pptx会转换失败。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。