您的位置:首页 > 编程语言 > Java开发

使用Adobe Reader控件结合Java实现PDF打印功能

2015-11-23 00:00 896 查看
摘要: 需求就是在页面选中要打印的PDF文件,实现PDF打印功能,需要支持批量打印。最开始使用Applet实现,但问题太多放弃,又试用过一些收费控件都不是特别理想,最终选择的这种方式比较稳定。

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版本下不能直接预览,会显示一个下载页面点击直接打开才能预览。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息