本人技术小白一枚,前些天Boss让我写一个office在线预览的一个功能,各种找资料,总结一下我觉得比较好用的方法
网上大概有这几种office在线预览的方法
第一种
利用office online实现在线预览
Office平台提供了通过url的指向达到预览效果
http://view.officeapps.live.com/op/view.aspx?src=
后面的src填写文档上传到服务器的地址,地址需要通过用URLEncode进行编译
例:
http://view.officeapps.live.com/op/view.aspx?src=http%3a%2f%2fvideo.ch9.ms%2fbuild%2f2011%2fslides%2fTOOL-532T_Sutter.pptx
参照链接:
https://blog.youkuaiyun.com/csdn_cjgu/article/details/69389474
优点:这个功能由Office提供所以只需要拼接地址
缺点:文档的访问地址不能直接使用 ip,需要通过域名访问,并且端口必须是 80 端口,
Word、ppt文档的大小不能超过10M,Excel不能超过5M
第二种
1.通过第三方工具openoffice,将word、excel、ppt、txt等文件转换为pdf文件,
2.通过swfTools将pdf文件转换成swf格式的文件;
3.通过FlexPaper文档组件在页面上进行展示。
参照链接:
https://blog.youkuaiyun.com/tmac937436/article/details/70799687?locationNum=14&fps=1
总结一下这种方法的利弊,
优点:openoffice有各种版本,支持跨平台,转换速度快;
缺点:转换的样式会有缺损,Excel和openoffice完美不兼容 = . = ,转换的时候会出现折行,切分等情况,效果很不理想;
FlexPaper这个是用Flash插件显示的,展示的效果优点low。
第三种
利用poi实现office在线预览
-
public static void PoiWord07ToHtml (HttpServletRequest request) throws IOException{
-
-
String path= "C:\\Users\\Administrator\\Desktop\\";
-
String file = "C:\\Users\\Administrator\\Desktop\\word07.docx";
-
String file2 = "C:\\Users\\Administrator\\Desktop\\word07.html";
-
File f = new File(file);
-
if (!f.exists()) {
-
System.out.println( "Sorry File does not Exists!");
-
} else {
-
if (f.getName().endsWith( ".docx") || f.getName().endsWith( ".DOCX")) {
-
//读取文档内容
-
InputStream in = new FileInputStream(f);
-
XWPFDocument document = new XWPFDocument(in);
-
-
File imageFolderFile = new File(path);
-
//加载html页面时图片路径
-
XHTMLOptions options = XHTMLOptions.create().URIResolver( new BasicURIResolver( "./"));
-
//图片保存文件夹路径
-
options.setExtractor( new FileImageExtractor(imageFolderFile));
-
OutputStream out = new FileOutputStream( new File(file2));
-
XHTMLConverter.getInstance().convert(document, out, options);
-
out.close();
-
} else {
-
System.out.println( "Enter only MS Office 2007+ files");
-
}
-
}
-
-
}
总结一下这种方法的利弊
优点:纯java代码不需要第三方软件,poi对于Excel的解析比较好,可以完美转换
缺点:jar包真的好难找啊,各种版本不兼容问题,比如word03和word07生成的分别是.doc和docx,poi对于.doc不识别,然后各种报错,由于生成的是Html所以它会把Word中的图片单独存放在一个文件下很占空间。
第四种
使用jacob实现office转换pdf达到预览功能
pom文件中引用
<dependency> <groupId>net.sf.jacob-project</groupId> <artifactId>jacob</artifactId> <version>1.14.3</version> </dependency> <dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version> </dependency> <!--poi--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.14-beta1</version>
</dependency>
网上查找jacob对应版本包把jacob-1.14.3-x64.dll复制到需要在Java\jdk1.8.0\jre\bin目录下,
经过多次测试发现jacob对于Excel的转换有些问题,所以Excel的转换我用的是poi
自定义一个工具类Word2Pdf
import com.jacob.activeX.ActiveXComponent; import com.jacob.com.Dispatch; import com.jacob.com.Variant; import java.io.*; public class Word2Pdf { static final int wdDoNotSaveChanges = 0;// 不保存待定的更改。 static final int wdFormatPDF = 17;// word转PDF 格式 static final int ppSaveAsPDF = 32;// ppt 转PDF 格式 public static void main(String[] args) throws IOException { } public void word2pdf(String wordPath,String target,String wordName,String suffix){ System.out.println("启动Word"); long start = System.currentTimeMillis(); String source = wordPath + wordName + suffix; target = target + wordName ; ActiveXComponent app = null; try { app = new ActiveXComponent("Word.Application"); app.setProperty("Visible", false); app.setProperty("DisplayAlerts", new Variant(false)); Dispatch docs = app.getProperty("Documents").toDispatch(); System.out.println("打开文档" + source); Dispatch doc = Dispatch.call(docs,// "Open", // source,// FileName false,// ConfirmConversions true // ReadOnly ).toDispatch(); System.out.println("转换文档到PDF " + target); File tofile = new File(target); //验证目标路径是否存在 if (tofile.exists()) { System.out.println("存在"); } Dispatch.call(doc,// "SaveAs", // target, // FileName wdFormatPDF); Dispatch.call(doc, "Close", false); long end = System.currentTimeMillis(); System.out.println("转换完成..用时:" + (end - start) + "ms."); // Cut.cutfile(str_s,str_d); } catch (Exception e) { System.out.println("========Error:文档转换失败:" + e.getMessage()); } finally { if (app != null) app.invoke("Quit", wdDoNotSaveChanges); } } public void ppt2pdf(String wordPath,String target,String wordName,String suffix){ System.out.println("启动PPT"); String source = wordPath + wordName + suffix; target = target + wordName ; long start = System.currentTimeMillis(); ActiveXComponent app = null; try { app = new ActiveXComponent("Powerpoint.Application"); Dispatch presentations = app.getProperty("Presentations").toDispatch(); System.out.println("打开文档" + source); Dispatch presentation = Dispatch.call(presentations,// "Open", source,// FileName true,// ReadOnly true,// Untitled 指定文件是否有标题。 false // WithWindow 指定文件是否可见。 ).toDispatch(); System.out.println("转换文档到PDF " + target); File tofile = new File(target); if (tofile.exists()) { tofile.delete(); } Dispatch.call(presentation,// "SaveAs", // target, // FileName ppSaveAsPDF); Dispatch.call(presentation, "Close"); long end = System.currentTimeMillis(); System.out.println("转换完成..用时:" + (end - start) + "ms."); } catch (Exception e) { System.out.println("========Error:文档转换失败:" + e.getMessage()); } finally { if (app != null) app.invoke("Quit"); } } }
再定义一个poi转换Html的一个类ExcelToHtml
import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComThread; import com.jacob.com.Dispatch; import com.jacob.com.Variant; import java.io.FileInputStream; import java.io.FileOutputStream; public class ExcelToHtml { private final static ExcelToHtml oOfficeToXML = new ExcelToHtml(); public static ExcelToHtml getInstance() { return oOfficeToXML; } public ExcelToHtml() { } /** * 因为poi转换的Html页面在浏览器中显示时会出现乱码问题,这里强制转换一下 * @param filePath */ public void html2utf(String filePath) { try { String content = "charset=utf-8"; String templateContent = ""; FileInputStream fileinputstream = new FileInputStream(filePath);// 读取模板文件 // 下面四行:获得输入流的长度,然后建一个该长度的数组,然后把输入流中的数据以字节的形式读入到数组中,然后关闭流 int lenght = fileinputstream.available(); byte bytes[] = new byte[lenght]; fileinputstream.read(bytes); fileinputstream.close(); // 通过使用默认字符集解码指定的 byte 数组,构造一个新的 //因为原来的html文件是gb2312格式,所以转为string时也要以GBK格式读取,不然依旧是乱码 templateContent = new String(bytes, "GBK"); templateContent = templateContent.replaceFirst("charset=gb2312", content); // 因为已经替换字符串了,所以使用UTF-8字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 byte tag_bytes[] = templateContent.getBytes("UTF-8"); FileOutputStream fileoutputstream = new FileOutputStream(filePath);// 建立文件输出流 fileoutputstream.write(tag_bytes); fileoutputstream.close(); } catch (Exception e) { System.out.print(e.toString()); } } public boolean ExceltoHtml(String wordPath,String original_name,String target,String wordName,String suffix) { ComThread.InitSTA(); ActiveXComponent activexcomponent = new ActiveXComponent("Excel.Application"); String source = wordPath + original_name + suffix; target = target + wordName; boolean flag = false; try { activexcomponent.setProperty("Visible", new Variant(false)); Dispatch dispatch = activexcomponent.getProperty("Workbooks").toDispatch(); Dispatch dispatch1 = Dispatch.invoke(dispatch, "Open", 1, new Object[] { source, new Variant(false), new Variant(true) }, new int[1]).toDispatch(); Dispatch.call(dispatch1, "SaveAs", target, new Variant(44)); Variant variant = new Variant(false); Dispatch.call(dispatch1, "Close", variant); flag = true; } catch(Exception exception) { System.out.println("|||" + exception.toString()); } finally { activexcomponent.invoke("Quit", new Variant[0]); ComThread.Release(); ComThread.quitMainSTA(); } return flag; } }
主要的两个类已完成,因为这只是一个小demo所以代码可能有些不太规范
controller类
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import pojo.UpFile; import tools.ExcelToHtml; import tools.Word2Pdf; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; @Controller @RequestMapping("/sys") public class controller { Word2Pdf word2Pdf = new Word2Pdf(); @RequestMapping("/index") public ModelAndView index(){ ModelAndView modelAndView = new ModelAndView(); // Word2Pdf word2Pdf = new Word2Pdf(); // word2Pdf.word2pdf("G:\\Test\\","G:\\Test\\PDF\\","",".doc"); // modelAndView.setViewName("index"); return modelAndView; } @RequestMapping(value="/upload.json",method=RequestMethod.POST) @ResponseBody public Map<Object,Object> upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception { UpFile upFile = new UpFile(); Map<Object,Object> map = new HashMap<Object, Object>(); String suffix = file.getOriginalFilename().substring( file.getOriginalFilename().lastIndexOf(".")); String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")); String time = new SimpleDateFormat("yyyyMMddHHmmssSSS") .format(new Date() ); String filePath = request.getSession().getServletContext().getRealPath("upload/"); String target = "G:\\Test_02\\target\\backend\\statics\\pdf\\"; // String FileName = "\\statics\\pdf\\"+fileName+".pdf"; String FileName = "/statics/pdf/"+fileName+".pdf"; // 上传到/target/backend/upload/的暂存文件夹下 File dir = new File(filePath,fileName+suffix); file.transferTo(dir); if (suffix.equals(".doc")||suffix.equals(".docx")){ WordToPdf(filePath,target,fileName,suffix); } else if (suffix.equals(".ppt")||suffix.equals(".pptx")){ PptToPdf(filePath,target,fileName,suffix); } else if (suffix.equals(".xls")||suffix.equals(".xlsx")) { //有些浏览器会把html名字中的中文进行编译,导致404 所以我名字我就用时间戳代替了 //原文件名 String original_name = fileName; //更改后的名字 String changeName = "Html" + time; ExcelToHtml(filePath, original_name, changeName, suffix); FileName = "\\statics\\Html\\" + changeName + ".htm"; } map.put("filename",FileName); return map; } public void WordToPdf(String filePath,String target,String fileName,String suffix){ word2Pdf.word2pdf(filePath,target,fileName,suffix); } public void PptToPdf(String filePath,String target,String wordName,String suffix){ word2Pdf.ppt2pdf(filePath,target,wordName,suffix); } public void ExcelToHtml(String filePath,String original_name,String wordName,String suffix){ ExcelToHtml excelToHtml = new ExcelToHtml(); excelToHtml.ExceltoHtml(filePath,original_name,"G:\\Test_02\\target\\backend\\statics\\Html\\",wordName,suffix); excelToHtml.html2utf("G:\\Test_02\\target\\backend\\statics\\Html\\"+wordName+".htm"); } }
前台页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="/statics/jquery-3.2.1.min.js"></script> <script type="text/javascript"> var filePath = ""; function load(){ if (filePath==""||filePath.length==0){ alert("请先上传文件"); } document.getElementById("iframe").src=filePath } function test(){ var form = new FormData(document.getElementById("form")); $.ajax({ url:"/sys/upload.json", type:"post", data:form, cache: false, processData: false, contentType: false, success:function(data){ filePath = (data.filename); alert("上传成功"); }, error:function(e){ alert(e.error); window.clearInterval(timer); } }) } </script> </head> <body> <form class="form" enctype="multipart/form-data" id="form"> 选择文件:<input type="file" name="file" width="180px"> <input type="button" value="上传" onclick="test()"> <input type="button" value="预览" onclick="load()"> </form> <iframe src="" id="iframe" width="100%" height="650px"/> </body> </html>
总结一下jacob的利弊
优点:相对于其他方法可以较为完好的转换
缺点:转换效率很低,通常一个Word需要4s左右,大一点的文件就很慢了,不支持跨平台,只能在windows下运行。
由于博主作为一个小菜鸟第一次博客一些不足和缺失请多多担待
本文介绍了四种不同的Office在线预览技术:Office Online、OpenOffice转换、Apache POI以及Jacob。详细分析了每种方法的优点和缺点,如Office Online对域名和端口的要求,OpenOffice的样式损失,POI的兼容性问题以及Jacob的转换效率低。最终,博主作为技术新手分享了自己的实践心得。
1198

被折叠的 条评论
为什么被折叠?



