PDF的生成与下载
来源:互联网 发布:万网 解析 端口 编辑:程序博客网 时间:2024/05/16 17:16
近期做一个生成PDF的直接下载功能,当然一般有两种方法,一种是代码实现其内容,代码实现样式可参考 http://rensanning.iteye.com/blog/1538689,另一种通过制作模板向其添加数据生成PDF下载,模板制作方式参考: http://wenku.baidu.com/linkurl=3dKL69zhDcMywL4hNmvmLHP2MvG2oT6ahfqijlIVpcvz7W_xi6fYEoWQQBMzi8b2360KOvJFB9CCgKbvAN01Zr2k0LKnyOqPaxcm5vYdsCO;
由于本业务要求输出的PDF较为复杂,所以选择通过模板实现其样式进行PDF的输出,首先准备相应的jar包,
<pre name="code" class="java">核心包:<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.3</version></dependency>中文支持包:<dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version></dependency>中文支持的话其他版本有问题,上述两个版本同时使用通过测试的;
因为项目用的是SpringMVC,所以控制层代码:
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="java">@RequestMapping("/download") public String pdfDownload(Model model) {//添加数据model.addAttribute("data", "大哥")); return "contract"; }配置文件:
<pre name="code" class="java"><!-- 按照BeanName解析视图 --><bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/><!-- 定义Pdf模版视图 --> <bean id="contract" class="com.netease.cpp.view.PdfStamperView"> <property name="url" value="" /> </bean>
Spring框架给我们集成了读取模板生成PDF的类AbstractPdfStamperView;但是其只集成的是itext2.7.0以前的版本,现在已变成itextpdf5.4以上,itext有些方法被itextpdf重写,导致我们不能直接使用AbstractPdfStamperView,解决方式是我们写个类去继承AbstractUrlBasedView,复制AbstractPdfStamperView的方法,重新引入相关方法,
/** * PDF模板视图 ;重新定义AbstractPdfStamperView类重写其中相关方法 */public abstract class AbstractPdf4StamperView extends AbstractUrlBasedView { public AbstractPdf4StamperView(){setContentType("application/pdf");}@Overrideprotected boolean generatesDownloadContent() {return true;}/** * 通过model判断读取模板 ,关闭相关流 */@Overrideprotected final void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) { // IE workaround: write into byte array first. <span style="white-space:pre"></span>ByteArrayOutputStream baos = createTemporaryOutputStream();String path = request.getSession().getServletContext().getRealPath("/"); String TemplatePDF = path + "WEB-INF/pdftemple/"+temp+".pdf"; PdfReader reader = null;PdfStamper stamper = null;try {reader = new PdfReader(TemplatePDF);stamper = new PdfStamper(reader, baos);mergePdfDocument(model, stamper, request, response);} catch (IOException ex) {LoggerUtil.error("读取模板异常", ex);} catch (PDFException e) {LoggerUtil.error("生成pdf异常", e);} catch (DocumentException dx){LoggerUtil.error("生成pdf异常", dx);} finally{if (stamper != null) {try {stamper.close();} catch (IOException e) {LoggerUtil.error("关闭IO异常", e);} catch (DocumentException dx){LoggerUtil.error("生成失败", dx);}}if(reader != null ){reader.close();}}// Flush to HTTP response.response.setContentType(getContentType());response.setContentLength(baos.size());// Flush byte array to servlet output stream.ServletOutputStream out = null;try {out = response.getOutputStream();baos.writeTo(out);out.flush();} catch (IOException e) {LoggerUtil.error("writeToResponse is Exception", e);} finally {if (out != null) {try {out.close();} catch (IOException e) {LoggerUtil.error("关闭IO异常", e);}}if (baos != null){try {baos.close();} catch (IOException e) {LoggerUtil.error("关闭IO异常", e);}}}}protected PdfReader readPdfResource() throws IOException {return new PdfReader(getApplicationContext().getResource(getUrl()).getInputStream());} protected abstract void mergePdfDocument(Map<String, Object> model, PdfStamper stamper,HttpServletRequest request, HttpServletResponse response) throws PDFException;}原本renderMergedOutputModel方法只有下面几行:
@Overrideprotected final void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {// IE workaround: write into byte array first.ByteArrayOutputStream baos = createTemporaryOutputStream();PdfReader reader = readPdfResource();PdfStamper stamper = new PdfStamper(reader, baos);mergePdfDocument(model, stamper, request, response);stamper.close();// Flush to HTTP response.writeToResponse(response, baos);}在测试过程中发现已加载的模板无法删除,才发现框架提供的方法没有关闭相关的流,所以也在该类下手动关闭了相关流,注意的是模板放在maven构建的resource下无法被加载,也能是模板被编译的故,具体原因待解,所以把模板放在了WEB-INF下,这也是原先框架放置的地方,因为在配置pdf模板视图是有个URL参数就是添的web-inf;只不过我要选择不同的模板所以重写了读取模板的方法。
接下来是写一个类去继承AbstractPdf4StamperView然后重写mergePdfDocument方法进行数据的添加:
package com.netease.cpp.view;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.util.Calendar;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.itextpdf.text.DocumentException;import com.itextpdf.text.pdf.AcroFields;import com.itextpdf.text.pdf.PdfStamper;import com.netease.cpp.exception.PDFException;import com.netease.cpp.util.LoggerUtil;/** * 生成PDF */public class PdfStamperView extends AbstractPdf4StamperView { @SuppressWarnings("unchecked") @Override protected void mergePdfDocument(Map<String, Object> model, PdfStamper stamper, HttpServletRequest request,HttpServletResponse response) throws PDFException { // 设置response方式,使执行此controller时候自动出现下载页面,而非直接使用pdf打开 response.setContentType("APPLICATION/OCTET-STREAM"); try {response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode(filename, "UTF-8"));} catch (UnsupportedEncodingException e) {LoggerUtil.error("文件名编码失败", e);throw new PDFException(e);} AcroFields fields = stamper.getAcroFields();try {fillData(fields,model);} catch (IOException ex) {LoggerUtil.error("向pdf添加数据失败", ex);throw new PDFException(ex);} catch (DocumentException dx){LoggerUtil.error("向pdf添加数据失败", dx);} stamper.setFormFlattening(true);//必须有,否则输出的pdf是一个表单} //给模板添加数据 @SuppressWarnings("unchecked") private void fillData(AcroFields fields,Map<String, Object> model)throws IOException, DocumentException { Map<String, String> data=( Map<String, String>) model.get("data"); for (String key : data.keySet()) { String value = data.get(key); fields.setField(key, value); } } }
代码中写出了一些注意事项,这样就能实现PDF的下载了
0 0
- PDF的生成与下载
- java实现pdf的生成下载打印,java生成pdf电子账单,java生成pdf合同模板
- pdf数据表格的生成与导出
- jasperreport 生成pdf下载功能
- springmvc 生成pdf,并下载
- springmvc 生成pdf,并下载
- pdf文档的下载
- PDF文件的生成
- PDF的生成方案
- PDF的生成方案
- PDF文件的生成
- 下载与生产pdf文件
- pdf文档的下载与查看 jsp页面
- Android+应用签名的枷锁与革新.pdf 免费下载
- java 利用itext生成PDF并下载
- Echarts图表之插件生成PDF下载
- ftl 生成pdf 可打印、可下载
- 基于PHP与XML的PDF文档生成技术
- jquery的.on()支持的事件
- 轻松学习之 IMP指针的作用
- ThinkPHP & jQuery.ajax 登录功能,无法重定向,自动刷新
- android上px与dp相互转换代码
- C# 原样复制excel工作表
- PDF的生成与下载
- 十道海量数据处理面试题与十个方法大总结
- 页面传递多条参数到后台
- oracle 删除用户,提示“无法删除当前已连接的用户”
- 使用ViewServer检测布局复杂性
- android解析xml简单分析
- android adb命令
- JavaScript 脑补
- Python点滴02_Python3打开中文文本时报错的一种处理方法