IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [转]pdf2htmlEX实现pdf转html

    zhoubl668发表于 2016-11-28 19:18:11
    love 0

    首先要感谢pdf2htmlEX的作者Lu Wang,该软件是一个pdf转html的开源软件,效果非常理想。下面两张图片是html和pdf视图下的截图:




    windows下载地址pdf2htmlEX-v1.0-win32-static


    本人开发的一个功能:文档在线阅读,要求能够支持移动终端浏览器在线阅读。考虑过将文档先转pdf,然后在将pdf转swf,利用flexpaper在前端浏览器访问。但是由于safari浏览器不支持flash,所以这种方式不太适合。也测试过火狐的pdf.js,但是这个框架在safari中出现中文乱码,同样不行。最后,经过测试,只有使用pdf2htmlEX转的html在各个浏览器上展示效果均不错,所以选择该软件。

    第一步:下载pdf2html。

    第二步:修改pdf2html自带的js文件pdf2htmlEX.min.js。原因:移动终端浏览器对CSS定位absolute的支持有问题(不会出现滚动条),所以需要为所有页面的容器设置高度,这样,手机浏览器就可以出现滚动条了。修改和添加的js代码如下:

    [html] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. 文件最后加上:  
    2. window.onload=function(){  
    3.     var eles = document.getElementsByClassName('pf w0 h0');  
    4.     var height = 0;  
    5.     for(var i=0,len=eles.length;i<len;i++){  
    6.         height +=eles[i].scrollHeight+20;  
    7.     }  
    8.     if(height>0)  
    9.     document.getElementById('page-container').style.height=height+'px';  
    10. }  
    [javascript] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /*注释下面这段代码,因为手机浏览器无法触发滚动事件 
    2.     <span style="white-space:pre">  </span>this.container.addEventListener('scroll', function() { 
    3.       <span style="white-space:pre">        </span>self.update_page_idx(); 
    4.       <span style="white-space:pre">        </span>self.schedule_render(true); 
    5.    <span style="white-space:pre">   </span>}, false); 
    6. */  
    7. /*新增,使用document对象上滚动加载页面数据,这样可以兼容手机浏览器*/  
    8. <span style="white-space:pre">  </span>document.addEventListener('scroll', function() {  
    9.         <span style="white-space:pre">  </span>self.update_page_idx();  
    10.         <span style="white-space:pre">  </span>self.schedule_render(true);  
    11.       <span style="white-space:pre">    </span>}, false);  

    第三步:编写java处理类

    [java] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. public class Pdf2htmlEXUtil {  
    2.   
    3.     /** 
    4.      * 调用pdf2htmlEX将pdf文件转换为html文件 
    5.      * @param command 调用exe的字符串 
    6.      * @param pdfName 需要转换的pdf文件名称 
    7.      * @param htmlName 生成的html文件名称 
    8.      * @return 
    9.      */  
    10.     public static boolean pdf2html(String command,String pdfName,String htmlName){  
    11.         Runtime rt = Runtime.getRuntime();  
    12.         try {  
    13.             Process p = rt.exec(command);  
    14.             StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");                
    15.               // kick off stderr    
    16.             errorGobbler.start();    
    17.             StreamGobbler outGobbler = new StreamGobbler(p.getInputStream(), "STDOUT");    
    18.               // kick off stdout    
    19.             outGobbler.start();   
    20.             int w = p.waitFor();  
    21.             System.out.println(w);  
    22.             int v = p.exitValue();  
    23.             System.out.println(v);  
    24.             return true;  
    25.         } catch (Exception e) {  
    26.             e.printStackTrace();  
    27.         }  
    28.         return false;  
    29.     }  
    30.       
    31.     public static void main(String[] args) {  
    32.         pdf2html("D:\\pdf2htmlEX-v1.0\\pdf2htmlEX.exe D:\\v.pdf hello.html","v.pdf","v2.html");  
    33.     }  
    34. }  
    处理Runtime.exec()一直阻塞的类:如果没有这个类,p.waitFor()将会一直等待,这是从这里找到的解决方法

    [java] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. import java.io.BufferedReader;  
    2. import java.io.IOException;  
    3. import java.io.InputStream;  
    4. import java.io.InputStreamReader;  
    5. import java.io.OutputStream;  
    6. import java.io.PrintWriter;  
    7.   
    8. /** 
    9.  * 用于处理Runtime.getRuntime().exec产生的错误流及输出流 
    10.  * @author shaojing 
    11.  * 
    12.  */  
    13. public class StreamGobbler extends Thread {  
    14.     InputStream is;  
    15.     String type;  
    16.     OutputStream os;  
    17.           
    18.     StreamGobbler(InputStream is, String type) {  
    19.         this(is, type, null);  
    20.     }  
    21.   
    22.     StreamGobbler(InputStream is, String type, OutputStream redirect) {  
    23.         this.is = is;  
    24.         this.type = type;  
    25.         this.os = redirect;  
    26.     }  
    27.       
    28.     public void run() {  
    29.         InputStreamReader isr = null;  
    30.         BufferedReader br = null;  
    31.         PrintWriter pw = null;  
    32.         try {  
    33.             if (os != null)  
    34.                 pw = new PrintWriter(os);  
    35.             isr = new InputStreamReader(is);  
    36.             br = new BufferedReader(isr);  
    37.             String line=null;  
    38.             while ( (line = br.readLine()) != null) {  
    39.                 if (pw != null)  
    40.                     pw.println(line);  
    41.                 System.out.println(type + ">" + line);      
    42.             }  
    43.             if (pw != null)  
    44.                 pw.flush();  
    45.         } catch (IOException ioe) {  
    46.             ioe.printStackTrace();    
    47.         } finally{  
    48.             try {  
    49.                 if(pw!=null)  
    50.                     pw.close();  
    51.                 if(br!=null)  
    52.                     br.close();  
    53.                 if(isr!=null)  
    54.                     isr.close();  
    55.             } catch (IOException e) {  
    56.                 e.printStackTrace();  
    57.             }  
    58.         }  
    59.     }  
    60. }   
    一个完整的高保真pdf转html例子就完成了。使用pdf2html,本人摸索了2天,终于在今天搞定,特此记录一下。

    pdf2html命令用法:

    [html] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. 用法: pdf2htmlEX [options] <input.pdf> [<output.html>]  
    2.   -f,--first-page <int>         需要转换的起始页 (默认: 1)  
    3.   -l,--last-page <int>          需要转换的最后一页 (默认: 2147483647)  
    4.   --zoom <fp>                   缩放比例  
    5.   --fit-width <fp>              适合宽度 <fp> 像素  
    6.   --fit-height <fp>             适合高度 <fp> 像素  
    7.   --use-cropbox <int>           使用剪切框 (default: 1)  
    8.   --hdpi <fp>                   图像水平分辨率 (default: 144)  
    9.   --vdpi <fp>                   图像垂直分辨率 (default: 144)  
    10.   --embed <string>              指定哪些元素应该被嵌入到输出  
    11.   --embed-css <int>             将CSS文件嵌入到输出中 (default: 1)  
    12.   --embed-font <int>            将字体文件嵌入到输出中 (default: 1)  
    13.   --embed-image <int>           将图片文件嵌入到输出中 (default: 1)  
    14.   --embed-javascript <int>      将javascript文件嵌入到输出中 (default: 1)  
    15.   --embed-outline <int>         将链接嵌入到输出中 (default: 1)  
    16.   --split-pages <int>           将页面分割为单独的文件 (default: 0)  
    17.   --dest-dir <string>           指定目标目录 (default: ".")  
    18.   --css-filename <string>       生成的css文件的文件名 (default: "")  
    19.   --page-filename <string>      分割的网页名称  (default:"")  
    20.   --outline-filename <string>   生成的链接文件名称 (default:"")  
    21.   --process-nontext <int>       渲染图行,文字除外 (default: 1)  
    22.   --process-outline <int>       在html中显示链接 (default: 1)  
    23.   --printing <int>              支持打印 (default: 1)  
    24.   --fallback <int>              在备用模式下输出 (default: 0)  
    25.   --embed-external-font <int>   嵌入局部匹配的外部字体 (default: 1)  
    26.   --font-format <string>        嵌入的字体文件后缀 (ttf,otf,woff,svg) (default: "woff")  
    27.   --decompose-ligature <int>    分解连字-> fi (default:0)  
    28.   --auto-hint <int>             使用fontforge的autohint上的字体时不提示 (default: 0)  
    29.   --external-hint-tool <string> 字体外部提示工具 (overrides --auto-hint) (default: "")  
    30.   --stretch-narrow-glyph <int>  伸展狭窄的字形,而不是填充 (default: 0)  
    31.   --squeeze-wide-glyph <int>    收缩较宽的字形,而不是截断 (default: 1)  
    32.   --override-fstype <int>       clear the fstype bits in TTF/OTF fonts (default:0)  
    33.   --process-type3 <int>         convert Type 3 fonts for web (experimental) (default: 0)  
    34.   --heps <fp>                   合并文本的水平临界值,单位:像素(default: 1)  
    35.   --veps <fp>                   vertical threshold for merging text, in pixels (default: 1)  
    36.   --space-threshold <fp>        断字临界值 (临界值 * em) (default:0.125)  
    37.   --font-size-multiplier <fp>   一个大于1的值增加渲染精度 (default: 4)  
    38.   --space-as-offset <int>       把空格字符作为偏移量 (default: 0)  
    39.   --tounicode <int>             如何处理ToUnicode的CMap (0=auto, 1=force,-1=ignore) (default: 0)  
    40.   --optimize-text <int>         尽量减少用于文本的HTML元素的数目 (default: 0)  
    41.   --bg-format <string>          指定背景图像格式 (default: "png")  
    42.   -o,--owner-password <string>  所有者密码 (为了加密文件)  
    43.   -u,--user-password <string>   用户密码 (为了加密文件)  
    44.   --no-drm <int>                覆盖文档的 DRM 设置 (default: 0)  
    45.   --clean-tmp <int>             转换后删除临时文件 (default: 1)  
    46.   --data-dir <string>           指定的数据目录 (default: ".\share\pdf2htmlEX")  
    47.   --debug <int>                 打印调试信息 (default: 0)  
    48.   -v,--version                  打印版权和版本信息  
    49.   -h,--help                     打印使用帮助信息  


    本人使用的版本时v0.11的和v1的版本有一些区别,主要是作者重新编写了pdftohtmlEX.js所以需要对照上面的js做相应修改

    [javascript] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. window.onload=function(){  
    2.     var eles = document.getElementsByClassName('pd w0 h0');  
    3.     var height = 0;  
    4.     for(var i=0,len=eles.length;i<len;i++){  
    5.         height +=eles[i].scrollHeight+20;  
    6.     }  
    7.     if(height>0){  
    8.         document.getElementById('page-container').style.height=height+'px';  
    9.         document.getElementById('page-container').style.overflow='hidden';  
    10.     }  
    11. }  

    [javascript] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. //this.$container.scroll(function(){ _.schedule_render(); });  
    2.   $(document).scroll(function(){_.schedule_render();});  
    修改之后的Pdf2htmlEXUtil
    [java] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. package cn.com.oims.util;  
    2.   
    3. import cn.com.oims.config.BaseConfig;  
    4.   
    5. /**@author liuzhengyong 
    6.  * @version 1.0 时间:2013-12-30  下午2:24:10 
    7.  * pdf文件转html工具类 
    8.  */  
    9. public class Pdf2htmlEXUtil {  
    10. <span style="white-space:pre">  </span>private static final int OS = 2;  
    11.     /** 
    12.      * 调用pdf2htmlEX将pdf文件转换为html文件 
    13.      * @param exeFilePath pdf2htmlEX.exe文件路径 
    14.      * @param pdfFile pdf文件绝对路径 
    15.      * @param [destDir] 生成的html文件存放路径 
    16.      * @param htmlName 生成的html文件名称 
    17.      * @return 
    18.      */  
    19.     public static boolean pdf2html(String exeFilePath,String pdfFile,String destDir,String htmlFileName){  
    20.         if(OS==2){//linux  
    21.             return pdf2html_linux(htmlFileName, htmlFileName, htmlFileName);  
    22.         }  
    23.         if(!(exeFilePath!=null&&!"".equals(exeFilePath)  
    24.                 &&pdfFile!=null&&!"".equals(pdfFile)  
    25.                 &&htmlFileName!=null&&!"".equals(htmlFileName))){  
    26.             System.out.println("传递的参数有误!");  
    27.             return false;  
    28.         }  
    29.         Runtime rt = Runtime.getRuntime();  
    30.         StringBuilder command = new StringBuilder();  
    31.         command.append(exeFilePath).append(" ");  
    32.         if(destDir!=null&&!"".equals(destDir.trim()))//生成文件存放位置,需要替换文件路径中的空格  
    33.             command.append("--dest-dir ").append(destDir.replace(" ", "\" \"")).append(" ");  
    34.         command.append("--optimize-text 1 ");//尽量减少用于文本的HTML元素的数目 (default: 0)  
    35.         command.append("--zoom 1.4 ");  
    36.         command.append("--process-outline 0 ");//html中显示链接:0——false,1——true  
    37.         command.append("--font-format woff ");//嵌入html中的字体后缀(default ttf) ttf,otf,woff,svg  
    38.         command.append(pdfFile.replace(" ", "\" \"")).append(" ");//需要替换文件路径中的空格  
    39.         if(htmlFileName!=null&&!"".equals(htmlFileName.trim())){  
    40.             command.append(htmlFileName);  
    41.             if(htmlFileName.indexOf(".html")==-1)  
    42.                 command.append(".html");  
    43.         }  
    44.         try {  
    45.             System.out.println("Command:"+command.toString());  
    46.             Process p = rt.exec(command.toString());  
    47.             StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");                
    48.             //开启屏幕标准错误流  
    49.             errorGobbler.start();    
    50.             StreamGobbler outGobbler = new StreamGobbler(p.getInputStream(), "STDOUT");    
    51.             //开启屏幕标准输出流  
    52.             outGobbler.start();   
    53.             int w = p.waitFor();  
    54.             int v = p.exitValue();  
    55.             if(w==0&&v==0){  
    56.                 return true;  
    57.             }  
    58.         } catch (Exception e) {  
    59.             e.printStackTrace();  
    60.         }  
    61.         return false;  
    62.     }  
    63.       
    64.     public static boolean pdf2html_linux(String pdfFile,String destDir,String htmlFileName){  
    65.         if(!(pdfFile!=null&&!"".equals(pdfFile)  
    66.                 &&htmlFileName!=null&&!"".equals(htmlFileName))){  
    67.             System.out.println("传递的参数有误!");  
    68.             return false;  
    69.         }  
    70.         Runtime rt = Runtime.getRuntime();  
    71.         StringBuilder command = new StringBuilder();  
    72.         command.append("pdf2htmlEX").append(" ");  
    73.         if(destDir!=null&&!"".equals(destDir.trim()))//生成文件存放位置,需要替换文件路径中的空格  
    74.             command.append("--dest-dir ").append(destDir.replace(" ", "\" \"")).append(" ");  
    75.         command.append("--optimize-text 1 ");//尽量减少用于文本的HTML元素的数目 (default: 0)  
    76.         command.append("--process-outline 0 ");//html中显示链接:0——false,1——true  
    77.         command.append("--font-format woff ");//嵌入html中的字体后缀(default ttf) ttf,otf,woff,svg  
    78.         command.append(pdfFile.replace(" ", "\" \"")).append(" ");//需要替换文件路径中的空格  
    79.         if(htmlFileName!=null&&!"".equals(htmlFileName.trim())){  
    80.             command.append(htmlFileName);  
    81.             if(htmlFileName.indexOf(".html")==-1)  
    82.                 command.append(".html");  
    83.         }  
    84.         try {  
    85.             System.out.println("Command:"+command.toString());  
    86.             Process p = rt.exec(command.toString());  
    87.             StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");                
    88.             //开启屏幕标准错误流  
    89.             errorGobbler.start();    
    90.             StreamGobbler outGobbler = new StreamGobbler(p.getInputStream(), "STDOUT");    
    91.             //开启屏幕标准输出流  
    92.             outGobbler.start();   
    93.             int w = p.waitFor();  
    94.             int v = p.exitValue();  
    95.             if(w==0&&v==0){  
    96.                 return true;  
    97.             }  
    98.         } catch (Exception e) {  
    99.             e.printStackTrace();  
    100.         }  
    101.         return false;  
    102.     }  
    103. }  
    [java] view plain copy
    1.   


    在dos环境下的调用命名:

    D:\\pdf2htmlEX-v1.0\\pdf2htmlEX.exe d:\\test" "2 D:\\test" "1\\v1.pdf [v3.html]
    D:\\pdf2htmlEX-v1.0\\pdf2htmlEX.exe表示exe文件路径。后面的空格不能少
    d:\\test" "2表示转换之后的html存放位置,这里的" "为空格,dos环境下,所有空格必须使用""包裹,否则不能识别。后面的空格不能少
    D:\\test" "1\\v1.pdf表示pdf文件的位置。后面的空格不能少

    v3.html表示将pdf转为html文件的文件名。可选


    https://github.com/coolwanglu/pdf2htmlEX






沪ICP备19023445号-2号
友情链接