博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring boot itextPdf根据模板生成pdf文件
阅读量:5835 次
发布时间:2019-06-18

本文共 7766 字,大约阅读时间需要 25 分钟。

在开发一些平台中会遇到将数据库中的数据渲染到PDF模板文件中的场景,用itextPdf完全动态生成PDF文件的太过复杂,通过itextPdf/AcroFields可以比较简单的完成PDF数据渲染工作(PDF模板的表单域数据需定义名称)

  • Controller获取HttpServletResponse 输出流
package pdf.controller;import com.itextpdf.text.DocumentException;import service.PdfService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import java.io.IOException;import java.io.OutputStream;import javax.servlet.http.HttpServletResponse;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Controller;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.*;@Controller@RequestMapping(WebConstants.WEB_pdf + "/download")@Api(description = "pdf下载相关", tags = "Pdf.download")@NoAuthpublic class PdfDownloadController {    @Autowired    private PdfService PdfService;        @Value("${pdf.template.path}")    private String templatePath ;    @ApiOperation(value = "申请表下载")    @RequestMapping(value = "/download/{id}", method = RequestMethod.GET)    @ResponseBody     @NoLogin    public void download(@PathVariable("id") Long id, HttpServletResponse response) throws IOException, DocumentException {                //设置响应contenType        response.setContentType("application/pdf");        //设置响应文件名称        String fileName = new String("申请表.pdf".getBytes("UTF-8"),"iso-8859-1");        //设置文件名称        response.setHeader("Content-Disposition", "attachment; filename="+fileName);        //获取输出流        OutputStream out = response.getOutputStream();         PdfService.download(id, templatePath ,out);    }}
  • Service生成pdf数据响应输出流
1.业务service-负责实现获取pfd模板数据,数据库数据,实现动态赋值生成PDFpackage service.impl;import org.apache.commons.io.IOUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.util.ResourceUtils;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.OutputStream;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Optional;import com.itextpdf.text.DocumentException;import com.itextpdf.text.pdf.AcroFields;import com.itextpdf.text.pdf.BaseFont;import com.itextpdf.text.pdf.PdfReader;import com.itextpdf.text.pdf.PdfStamper;@Servicepublic class ApplyServiceImpl implements ApplyService {    @Override    public DetailDTO getDetail(Long id) {       // 获取业务数据       return null;    }        @Override    public Map
getPdfMapping(DetailDTO dto) { // TODO Auto-generated method stub // 获取pdf与数据库的数据字段映射map } @Override public void download(Long id, String templatePath, OutputStream out) { // TODO Auto-generated method stub DetailDTO dto = getDetail(id); Map
fieldMapping = getPdfMapping(dto); String filePath; byte[] pdfTemplate; ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream(); try { //获取模板文件路径 filePath = ResourceUtils.getURL(templatePath).getPath(); //获取模板文件字节数据 pdfTemplate = IOUtils.toByteArray(new FileInputStream(filePath)); //获取渲染数据后pdf字节数组数据 byte[] pdfByteArray = generatePdfByTemplate(pdfTemplate, fieldMapping); pdfOutputStream.write(pdfByteArray); pdfOutputStream.writeTo(out); pdfOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } finally { try { pdfOutputStream.close(); out.flush(); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override //itextPdf/AcroFields完成PDF数据渲染 public byte[] generatePdfByTemplate(byte[] pdfTemplate, Map
pdfParamMapping) { Assert.notNull(pdfTemplate, "template is null"); if (pdfParamMapping == null || pdfParamMapping.isEmpty()) { throw new IllegalArgumentException("pdfParamMapping can't be empty"); } PdfReader pdfReader = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfStamper stamper = null; try { // 读取pdf模板 pdfReader = new PdfReader(pdfTemplate); stamper = new PdfStamper(pdfReader, baos); //获取所有表单字段数据 AcroFields form = stamper.getAcroFields(); form.setGenerateAppearances(true); // 设置 ArrayList
fontList = new ArrayList<>(); fontList.add(getMsyhBaseFont()); form.setSubstitutionFonts(fontList); // 填充form for (String formKey : form.getFields().keySet()) { form.setField(formKey, pdfParamMapping.getOrDefault(formKey, StringUtils.EMPTY)); } // 如果为false那么生成的PDF文件还能编辑,一定要设为true stamper.setFormFlattening(true); stamper.close(); return baos.toByteArray(); } catch (DocumentException | IOException e) { LOGGER.error(e.getMessage(), e); } finally { if (stamper != null) { try { stamper.close(); } catch (DocumentException | IOException e) { LOGGER.error(e.getMessage(), e); } } if (pdfReader != null) { pdfReader.close(); } } throw new SystemException("pdf generate failed"); } /** * 默认字体 * * @return */ private BaseFont getDefaultBaseFont() throws IOException, DocumentException { return BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); } /** * 微软宋体字体 * * @return */ //设定字体 private BaseFont getMsyhBaseFont() throws IOException, DocumentException { try { return BaseFont.createFont("/msyh.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); } catch (DocumentException | IOException e) { LOGGER.error(e.getMessage(), e); } return getDefaultBaseFont(); }}
  • 数据库的数据到pdf字段的映射可以使用配置,建立数据字段映射表,通过反射
    可以将数据库数 据对象转为map,再通过定义的静态map映射表,将数据map转
    换为pdf表单数据map
BeanUtils.bean2Map(bean);    /**     * JavaBean对象转化成Map对象     * @param javaBean     * @return     */    public static Map bean2Map(Object javaBean) {        Map map = new HashMap();        try {            // 获取javaBean属性            BeanInfo beanInfo = Introspector.getBeanInfo(javaBean.getClass());            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();            if (propertyDescriptors != null && propertyDescriptors.length > 0) {                String propertyName = null; // javaBean属性名                Object propertyValue = null; // javaBean属性值                for (PropertyDescriptor pd : propertyDescriptors) {                    propertyName = pd.getName();                    if (!propertyName.equals("class")) {                        Method readMethod = pd.getReadMethod();                        propertyValue = readMethod.invoke(javaBean, new Object[0]);                        map.put(propertyName, propertyValue);                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }        return map;    }        字段映射配置    public class PdfMapping {        public final static Map
BASE_INFO_MAPPING = new HashMap() { { put("name", "partyA"); put("identity", "baseIdentity"); } }; }

转载地址:http://buycx.baihongyu.com/

你可能感兴趣的文章
31载春运 老铁警退休前站好最后一班岗
查看>>
南京少年交警帅气“开拔”
查看>>
特雷莎·梅严防议会架空 不排除延后英国“脱欧”
查看>>
陕西咸阳发掘秦墓75座 发现中西交流特色琉璃珠
查看>>
高雄购房调查:本地与外地人都看好三块区域
查看>>
中国环境损害司法鉴定机构突破100家
查看>>
首创置业“中国之家-和园”将在巴黎开工奠基
查看>>
NoSQL还是SQL?这一篇讲清楚
查看>>
建议收藏:你想要的开发和设计资源全部都在这里
查看>>
基于 D3.js 绘制动态进度条
查看>>
你为什么会被解雇? — Top 10 面试问题解析
查看>>
lodash源码分析之缓存使用方式的进一步封装
查看>>
Android复杂数据流的“高效”渲染(二)
查看>>
Android监测用户行为之中AOP编程之AspectJ实战
查看>>
用 Swift 来刷 leet code 吧 (1-20)
查看>>
20分钟上手 webAssembly
查看>>
SpringBoot下使用定时任务的方式全揭秘
查看>>
强引用、弱引用、软引用
查看>>
Maven构建自动化
查看>>
刷前端面经笔记(四)
查看>>