关于文件预览,网上比较流行的方案是: openoffice/libreoffice+swftools+jodconverter+flexpaper(跨平台) 1.我用的是libreoffice, 因为最开始我用的是openoffice, 但是发现openoffice有的格式转换不出来,而且有些复杂的word也转不成功(不报错,也没日志,就是没反应,这点很恼火,查了好久), 还有ppt,word的一些图表转换不出来,比如柱状图什么的 后来改用libreoffice就好了,格式也比较准确 转换的时候不要忘了开启服务, D:\LibreOffice 4\program\soffice.exe -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard linux下是: ./soffice --headless --accept="socket,host=127.0.0.1,port=8100;urp;" --nofirststartwizard & 注意不要忘了后面的符号 2.swftools 转换命令sourcePath -o targetPath -T 9 -f sourcePath是你要转换的文件,targetPath是要转换成的swf文件,-T 9 是转成9.0版本,这个版本支持分页加载(分页加载自己查吧) -f具体忘了,好像是转换所有字符,如果不加这参数,再用flexpaper搜索功能的时候有些功能会不正常(比如高亮显示)
如果在转换中遇到找不到F0类似的错误,这个是因为字体的问题,具体解决办法如下(以下资源比较好找,不写地址了): 首先下载xpdf-chinese-simplified.tar.gz,解压到xpdf目录下 下载gkai00mp.ttf和gbsn00lp.ttf两个字体拷贝到xpdf-chinese-simplified/CMap下 更改xpdf-chinese-simplified/add-to-xpdfrc这个文件,替换成以下内容:
#----- begin Chinese Simplified support package (2011-sep-02)cidToUnicode Adobe-GB1 xpdf安装目录/xpdf-chinese-simplified/Adobe-GB1.cidToUnicodeunicodeMap ISO-2022-CN xpdf安装目录/xpdf-chinese-simplified/ISO-2022-CN.unicodeMapunicodeMap EUC-CN xpdf安装目录/xpdf-chinese-simplified/EUC-CN.unicodeMapunicodeMap GBK xpdf安装目录/xpdf-chinese-simplified/GBK.unicodeMapcMapDir Adobe-GB1 xpdf安装目录/xpdf-chinese-simplified/CMaptoUnicodeDir xpdf安装目录/xpdf-chinese-simplified/CMapdisplayCIDFontTT Adobe-GB1 xpdf安装目录/xpdf-chinese-simplified/CMap/gkai00mp.ttfdisplayCIDFontTT Adobe-GB1 xpdf安装目录/xpdf-chinese-simplified/CMap/gbsn00lp.ttf#fontFileCC Adobe-GB1 /usr/..../gkai00mp.ttf#----- end Chinese Simplified support package 此时再用转换命令的时候,需要指定语言包:pdf2swf preview.pdf -o preview.swf -s languagedir=<span style="font-family: Arial, Helvetica, sans-serif;">xpdf安装目录/</span>xpdf-chinese-simplified -T 9 -f
3.jodconverter 我用的是jodconverter2.2.2,为什么用这个版本?因为这个版本之下的不能转换2007以上的office,而最新版的3.0(3.0还是3.3来着忘了)转换有bug 我转换的时候最开始用的就是最新版,结果我一个5m左右的2010word一直转换不成功,也没报错信息,就是上面openoffice那个情况,因为不确定是哪个原因所有写上面了 如果是maven项目的话: <dependency> <groupId>com.artofsolving</groupId> <artifactId>jodconverter</artifactId> <version>2.2.2</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> 这个包和slf4j有冲突,所有剔除下4.还有就是flexpaper了 我的版本是flexpaper2.2.4,获取flexpaper对象的方法是$FlexPaper('documentViewer'),documentView就是你的div的id 调用flexpaper的方法当然就是$FlexPaper('documentViewer').getTotalPages()了 如果flexpaper加载时间较长,这时候就需要用到事件了,比如ondocumentloaded(文档加载完成),直接这样: jQuery(function() { jQuery('#documentViewer').bind('onExternalLinkClicked',function(e,link){//do something}); jQuery('#documentViewer').bind('onProgress',function(e,loadedBytes,totalBytes){//do something}); jQuery('#documentViewer').bind('onDocumentLoading',function(e){//do something}); jQuery('#documentViewer').bind('onPageLoading',function(e,pageNumber){//do something}); jQuery('#documentViewer').bind('onCurrentPageChanged',function(e,pagenum){//do something}); jQuery('#documentViewer').bind('onDocumentLoaded',function(e,totalPages){//do something}); jQuery('#documentViewer').bind('onPageLoaded',function(e,pageNumber){//do something}); jQuery('#documentViewer').bind('onErrorLoadingPage',function(e,pageNumber){//do something}); jQuery('#documentViewer').bind('onDocumentLoadedError',function(e,errMessage){//do something}); jQuery('#documentViewer').bind('onDocumentPrinted',function(e){//do something});}); 我的版本里是有这么多事件,具体什么用,自己翻译吧~flexpaper要浏览的文件需要放在web环境下,path要写相对路径(因为它不支持绝对路径,不清楚为什么,反正我是没找到合适的答案) 如果你觉得麻烦,那它还支持流的方式加载swf,你可以再swfFile这里直接写上你的处理路径,比如/doc/preview,然后后台直接用response写回来就行了 flexpaper在加载大文档的时候会拖垮浏览器,比如我遇到个307页的pptx(据说pptx相对于ppt会小很多,应该是压缩比较厉害)才4m多,转换时间就不必说了,无法避免的(建议只转pdf,虽然可以直接转html和swf但是转swf很慢,转html的话文件会很大,我转一个4.8m的docx转完事40m,当然和我里面贴图多也有关系,并且有时候会出现卡死不断开soffice连接的问题,pdf最稳定,非要转html的话可以先转pdf然后用pdf2htmlex这个神器转换).所以后来就改成分页加载的方式了(主要当初没想到这种大文档会这么多),普通的分页加载方式就不多说了,网上有很多,而我采用的是流的方式,所以只能找怎么用流分页加载了.(废话好多,哈哈) 网上没合适的答案,自己摸索出flexpaper流的方式分页加载方法具体可以这么写 SWFFile:"{/doc_layout/preview_office$!{docFile.id}?pageNum=[*,0],$!{pageNumCount}}" 我用的velocity,这个字符串里的id就是我的业务id,pageNumCount是flash页数,页数的获取可以用itext这个jar获取pdf的页数(poi获取office页数不准,除非用openoffice).我们的文件都有个唯一的key,转换文件的时候就是原文件名加下划线加页码,所以我的办法是直接获取以这个key开头并以.swf结尾的文件的个数,代码如下:int pageNumCount = new File(path).getParentFile().list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.startsWith(docFileKey.substring(0, docFileKey.lastIndexOf("."))) && name.endsWith(".swf"); } }).length; pageNum是自己随便取,是要加载的页码,就当一个普通参数就行,但是[*,0]这个一定要这么写,逗号后没有空格,之后就是根据传到后台的页码自己决定加载哪页flash吧,
|