使用Adobe Reader控件结合Java实现PDF打印功能
2015-11-23 00:00
896 查看
摘要: 需求就是在页面选中要打印的PDF文件,实现PDF打印功能,需要支持批量打印。最开始使用Applet实现,但问题太多放弃,又试用过一些收费控件都不是特别理想,最终选择的这种方式比较稳定。
1、在页面引入控件,控件依赖任何第三方js库:
代码说明:<object></object>是IE下的控件引入方式,<embed></embed>是为了支持非IE浏览器。
object中的<param name="src">及<embed>的src属性就是PDF的路径,这里可以是本地磁盘路劲也可以是远程PDF的下载路径,总之要能识别是PDF文件即可。
为了支持批量打印,我使用的是合并多个PDF,再一起输出打印的方式。/file/download/mergePdf就是合并PDF的方法。$!reportAttParam就是我们系统中PDF文件上传后返回的ID,可以传多个。method=inline在线预览的方式打开PDF。
IE下可以直接调用打印:
IE判断代码:
2、合并多个PDF返回。
依赖jar包:
继续看合并PDF控制层代码
文件名编码部分的代码:
fileService.mergePdf关键代码:
最终把合并后的PDF显示在了浏览器,不过在有些IE版本下不能直接预览,会显示一个下载页面点击直接打开才能预览。
1、在页面引入控件,控件依赖任何第三方js库:
<object id="reportPrinterObj" width="100%" height="100%" classid="clsid:CA8A9780-280D-11CF-A24D-444553540000"> <param name="src" value="#webUrl("context")/file/download/mergePdf?method=inline&$!reportAttParam&_ws_sn=$math.random"> <comment> <embed name="reportPrinterObj" src="#webUrl("context")/file/download/mergePdf?method=inline&$!reportAttParam&_ws_sn=$math.random" width="100%" height="100%" href="http://www.adobe-reader-download.com/"> <noembed> No adobe reader support. </noembed> </embed> </comment> </object>
代码说明:<object></object>是IE下的控件引入方式,<embed></embed>是为了支持非IE浏览器。
object中的<param name="src">及<embed>的src属性就是PDF的路径,这里可以是本地磁盘路劲也可以是远程PDF的下载路径,总之要能识别是PDF文件即可。
为了支持批量打印,我使用的是合并多个PDF,再一起输出打印的方式。/file/download/mergePdf就是合并PDF的方法。$!reportAttParam就是我们系统中PDF文件上传后返回的ID,可以传多个。method=inline在线预览的方式打开PDF。
IE下可以直接调用打印:
if (isIE()) { var pdfReader = document.getElementById("reportPrinterObj"); //pdfReader.setShowToolbar(false); //pdfReader.setShowScrollbars(false); pdfReader.printWithDialog(); }
IE判断代码:
return ("ActiveXObject" in window);
2、合并多个PDF返回。
依赖jar包:
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>1.8.10</version> </dependency>
继续看合并PDF控制层代码
/** * 把PDF文件合并后下载 * * @param fileInfoVO 要合并的文件ID列表{@link FileInfoVO#getFileInfoList()} * @param httpServletRequest {@link HttpServletRequest} * @param httpServletResponse {@link HttpServletResponse} * @throws IOException {@link IOException} */ @RequestMapping(value = "/file/download/mergePdf", method = RequestMethod.GET) private void mergePdfAndDownload(FileInfoVO fileInfoVO, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException { String contentType = "application/pdf"; httpServletResponse.setContentType(contentType); String fileName = DataUtils.encodeFileName("合并后的文件.pdf", httpServletRequest); httpServletResponse.addHeader("Content-Disposition", fileInfoVO.getMethod() + ";filename=" + fileName); ServletOutputStream out = httpServletResponse.getOutputStream(); ResultVO resultVO = fileService.mergePdf(fileInfoVO, out); if (ResultVO.FAIL.equals(resultVO.getErrorCode())) { httpServletResponse.sendRedirect(UrlUtils.getCurUrl(httpServletRequest) + "/file/fileNotExist"); } }
文件名编码部分的代码:
/** * 对文件名做对应的编码处理,已兼容中文文件名 * * @param fileName 要做编码处理的文件名 * @return 编码后的文件名 */ public static String encodeFileName(String fileName, HttpServletRequest httpServletRequest) { String encodeFileName = fileName; if (httpServletRequest.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) { try { encodeFileName = URLEncoder.encode(fileName, "UTF-8"); } catch (UnsupportedEncodingException e) { LOGGER.error("编码文件名异常!{}", e.getMessage()); } } else { try { encodeFileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1"); } catch (UnsupportedEncodingException e) { LOGGER.error("编码文件名异常!{}", e.getMessage()); } } return encodeFileName; }
fileService.mergePdf关键代码:
@Override public ResultVO mergePdf(FileInfoVO fileInfoVO, OutputStream outputStream) throws IOException { ResultVO resultVO = new ResultVO(); if (CollectionUtils.isEmpty(fileInfoVO.getFileInfoList())) { resultVO.setErrorCode(ResultVO.FAIL); resultVO.setErrorMsg("没有要合并的PDF文件!"); return resultVO; } List<FileInfoVO> resultFiles; try { // 从文件服务器下载PDF resultFiles = getDownloadFiles(fileInfoVO.getFileInfoList(), Boolean.TRUE); } catch (Exception e) { resultFiles = null; } if (CollectionUtils.isEmpty(resultFiles)) { resultVO.setErrorCode(ResultVO.FAIL); resultVO.setErrorMsg("根据条件无法从平台获取要合并的PDF!"); return resultVO; } PDDocument destinationPdDocument = null; try { destinationPdDocument = getMergedPdfDocument(resultFiles, Boolean.FALSE); if (destinationPdDocument != null) { destinationPdDocument.save(outputStream); } else { resultVO.setErrorCode(ResultVO.FAIL); resultVO.setErrorMsg("要合并的文件都不是PDF文件!"); return resultVO; } outputStream.flush(); if (!ResultVO.SUCCESS.equals(resultVO.getErrorCode())) { resultVO.setErrorCode(ResultVO.SUCCESS); resultVO.setErrorMsg("PDF文件合并成功!"); } return resultVO; } catch (IOException | COSVisitorException e) { LOGGER.error("合并PDF异常-->", e); resultVO.setErrorCode(ResultVO.FAIL); resultVO.setErrorMsg("在合并PDF时发生未知异常!"); return resultVO; } finally { if (outputStream != null) { outputStream.close(); } if (destinationPdDocument != null) { destinationPdDocument.close(); } } }
@Override public PDDocument getMergedPdfDocument(List<FileInfoVO> resultFiles, boolean exitIfNotPdf) throws IOException { PDFMergerUtility pdfMergerUtility = new PDFMergerUtility(); PDDocument destinationPdDocument = null; for (FileInfoVO pdfFileInfo : resultFiles) { if (ArrayUtils.isNotEmpty(pdfFileInfo.getFileContent())) { ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(pdfFileInfo.getFileContent()); if (destinationPdDocument == null) { destinationPdDocument = PDDocument.load(byteArrayInputStream); } else { PDDocument appendPdDocument = PDDocument.load(byteArrayInputStream); pdfMergerUtility.appendDocument(destinationPdDocument, appendPdDocument); appendPdDocument.close(); } byteArrayInputStream.close(); } else { LOGGER.info("要合并的PDF内容为空,直接跳过,FileInfoVO-->{}", pdfFileInfo.toString()); } } return destinationPdDocument; }
最终把合并后的PDF显示在了浏览器,不过在有些IE版本下不能直接预览,会显示一个下载页面点击直接打开才能预览。
相关文章推荐
- 电子政务大厅
- Android通过系统打印功能实现PDF预览打印
- Java 使用jacob打印word文档
- javaScript实现网页表格打印功能
- Android实现PDF预览打印
- maven项目中打印和导出(表格)功能实现
- lodop实现打印,支持分页打印
- java原装代码完成pdf在线预览和pdf打印及下载
- Struts2学习笔记
- java中的值传递和引用传递
- 浅谈Struts2的命名空间及以传统形式返回json数据
- java文件输入输出
- Spring with Hibernate persistence and transactions
- Java基本数据类型与封装类的区别
- Java synchronized
- Java包 Package
- Java虚拟机类加载机制
- java内部类
- JAVA_SE基础——54.异常
- java提供的一些并发机制