场景描述
最近做一个项目前端是H5页面嵌套在app中的,其中有个功能是要展示一个pdf,遇到了一个问题就是带印章的pdf在直接查看的情况下ios中印章显示不出来,后来经过查阅资料发现是由于印章是加密过的,而用ios内置的webviewer查看的话没有对应的解密的插件,所以导致印章显示不出来。但是对于项目来说印章显示不出来整个pdf显示的意义就没有了,后来经过组内讨论就想着转化为图片去展示。经过查阅资料、对比了一下ICEPDF和pdfbox两种转化的开源项目,所用到的jar包就是下面资源中的内容。
http://download.youkuaiyun.com/detail/gao36951/9601359
解决方案
经过查阅资料发现有如下java相关的开源项目,网上摘录
1.PDFRenderer: 确实效率最高,但是缺少字体支持对大多数中文pdf处理不了(很奇怪为什么项目组还没做默认字体支持)
2.pdfbox:字体基本都可以转换,但容易内存溢出(我搞了几十M文件就不行了)
3.jpedal:效率不错。不过我这里好几个中文pdf文件就是生成缩略图不对,我还向项目组提bug了
4.icepdf它其实用了jpedal的字体支持库,确能支持我手上的中文pdf,而且效率不错(测试没遇到内存溢出)
接下来一个一个说
1.PDFRenderer:看了官网如下
https://java.net/projects/pdf-renderer/downloads
发现最新的jar包是 PDFRenderer-0.9.1.jar,而且是almost 5 years ago,5年多了,貌似最近都没有人维护 了,而且中文支持不好,所以就果断放弃了。
2.pdfbox:我们项目中就是用的这一种,由于与上面的网上摘录的应用场景不同,我们要处理的pdf是保单带印章的,所以文件大小并不大,但是必须要有印章,so这个可以满足我们的需求。jar包详见场景描述中的
http://download.youkuaiyun.com/detail/gao36951/9601359
具体代码摘要
public String pdf2Image(String urlStr, String policyNo, String datePath) throws PDFException, PDFSecurityException,
IOException {
//URL url = new URL(urlStr);
Map<String, String> params = new HashMap<String, String>();
params.put("url", urlStr);
InputStream in = null;
PDDocument doc = null;
try {
in = HttpClientHelper.loadFileFromURL(GetPdfBytesURL, params);//本项目是使用的流的方式,具体项目中如何使用视情况而定,支持File等其他方式
doc = PDDocument.load(in);
PDFRenderer renderer = new PDFRenderer(doc);
int pageCount = doc.getNumberOfPages();
for (int i = 0; i < pageCount; i++) {
BufferedImage image = renderer.renderImageWithDPI(i, PdfExchangeDpi); // Windows native DPI,PdfExchangeDpi是float类型的,越大文件越大,清晰度越高,可以根据需求来调整,我们使用的是80
File fileDirectory = new File(NfsImagePath + datePath);
if (!fileDirectory.exists()) {
fileDirectory.mkdirs();
}
File file = new File(NfsImagePath + datePath + policyNo + Constants.PNG_TYPE);
ImageIO.write(image, "PNG", file);
}
} finally {
if (in != null) {
in.close();
}
if (doc != null) {
doc.close();
}
}
return datePath + policyNo + Constants.PNG_TYPE;
}
3.jpedal:网上没有找到合适的jar包和文档,没有研究
4.icepdf实验代码,发现在linux 有问题,所以也没有用
public static String pdf2Image(String urlStr, String policyNo) throws PDFException, PDFSecurityException, IOException{
//URL url = new URL(urlStr);
Document document = new Document();
Map<String, String > params= new HashMap<String, String>();
params.put("url", urlStr);
InputStream in = HttpClientHelper.loadFileFromURL(GetPdfBytesURL, params);
document.setInputStream(in, null);
float scale = 2.5f;//缩放比例
float rotation = 0f;//旋转角度
File file = new File("/usr/local/tomcat7/webapps/hczface/app_img/"+policyNo+".jpg");
if(file.exists()){
logger.info(policyNo+".png已经存在,不再生成!");
return null;
}
for (int i = 0; i < document.getNumberOfPages(); i++) {
BufferedImage image = (BufferedImage)document.getPageImage(i, GraphicsRenderingHints.SCREEN, org.icepdf.core.pobjects.Page.BOUNDARY_CROPBOX, rotation, scale);
RenderedImage rendImage = image;
try {
ImageIO.write(rendImage, "jpg", file);
} catch (IOException e) {
e.printStackTrace();
return null;
}
image.flush();
}
document.dispose();
return policyNo+".jpg";
}
参考
http://javasogo.iteye.com/blog/1169234
http://www.oschina.net/question/250267_41156