package com.zudp.common.core.utils.pdf; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.*; import org.apache.commons.lang3.StringUtils; import org.apache.http.entity.ContentType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.util.*; /** * 根据PDF模板生成具体内容PDF */ public class PDFUtils { private static final Logger log = LoggerFactory.getLogger(PDFUtils.class); /** * @param fields * @param data * @throws IOException * @throws DocumentException */ private static void fillData(AcroFields fields, Map<String, String> data) throws IOException, DocumentException { List<String> keys = new ArrayList<String>(); Map<String, AcroFields.Item> formFields = fields.getFields(); for (String key : data.keySet()) { if (formFields.containsKey(key)) { String value = data.get(key); // 为字段赋值,注意字段名称是区分大小写的 fields.setField(key, value); keys.add(key); } } Iterator<String> itemsKey = formFields.keySet().iterator(); while (itemsKey.hasNext()) { String itemKey = itemsKey.next(); if (!keys.contains(itemKey)) { fields.setField(itemKey, " "); } } } /** * @param templatePdfPath 模板pdf路径 * @param generatePdf 生成pdf路径 * @param imagePath 图片路径 * @param fitWidth 图片宽 * @param fitHeight 图片高 * @param data 数据 */ public MultipartFile getPDFMultipartFile(String templatePdfPath, String generatePdf,String imageFiledName, String imagePath, Float fitWidth, Float fitHeight,Map<String, String> data) { ByteArrayOutputStream bos = null; InputStream inputStream = null ; MultipartFile file = null ; try { PdfReader reader = new PdfReader(templatePdfPath); // 将要生成的目标PDF文件名称 bos = new ByteArrayOutputStream(); // 使用中文字体 PdfStamper ps = new PdfStamper(reader, bos); BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(); // 取出报表模板中的所有字段 fontList.add(bf); AcroFields fields = ps.getAcroFields(); fields.setSubstitutionFonts(fontList); //设置图片 if (StringUtils.isNotBlank(imagePath)) { // 通过域名获取所在页和坐标,左下角为起点 int pageno = fields.getFieldPositions(imageFiledName).get(0).page; Rectangle signrect = fields.getFieldPositions(imageFiledName).get(0).position; float x = signrect.getLeft(); float y = signrect.getBottom(); // 读图片 Image image = Image.getInstance(imagePath); // 获取操作的页面 PdfContentByte under = ps.getOverContent(pageno); // 这里控制图片的大小 //image.scaleToFit(signrect.getWidth(), signrect.getHeight()); image.scaleToFit(fitWidth, fitHeight); // 添加图片 image.setAbsolutePosition(x, y); under.addImage(image); //移除图片的路径,要不然会把路径也设置上去 data.remove(imageFiledName); } // 必须要调用这个,否则文档不会生成的 如果为false那么生成的PDF文件还能编辑,一定要设为true fillData(fields, data); ps.setFormFlattening(true); ps.close(); byte[] testFile = bos.toByteArray(); inputStream = new ByteArrayInputStream(testFile); try { file = new MockMultipartFile(generatePdf, generatePdf, ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream); } catch (IOException e) { log.error(e.getMessage()); } } catch (Exception e) { log.error(e.getMessage()); } finally { if(inputStream != null ){ try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (bos != null) { try { bos.close(); } catch (IOException e) { log.error(e.getMessage()); } } } return file; } /** * 生成到本地 * @param templatePdfPath 模板pdf路径 * @param generatePdfPath 生成pdf路径 * @param data 数据 */ public String generatePDF(String templatePdfPath, String generatePdfPath, Map<String, String> data) { OutputStream fos = null; ByteArrayOutputStream bos = null; try { PdfReader reader = new PdfReader(templatePdfPath); // 将要生成的目标PDF文件名称 bos = new ByteArrayOutputStream(); // 使用中文字体 PdfStamper ps = new PdfStamper(reader, bos); BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(); // 取出报表模板中的所有字段 fontList.add(bf); AcroFields fields = ps.getAcroFields(); fields.setSubstitutionFonts(fontList); // 必须要调用这个,否则文档不会生成的 如果为false那么生成的PDF文件还能编辑,一定要设为true fillData(fields, data); ps.setFormFlattening(true); ps.close(); fos = new FileOutputStream(generatePdfPath); fos.write(bos.toByteArray()); fos.flush(); return generatePdfPath; } catch (Exception e) { log.error(e.getMessage()); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (bos != null) { try { bos.close(); } catch (IOException e) { log.error(e.getMessage()); } } } return null; } /** * 获取生成文件的MultipartFile * @param templatePdfPath * @param generatePdf * @param data * @return */ public MultipartFile getPDFMultipartFile(String templatePdfPath, String generatePdf, Map<String, String> data) { ByteArrayOutputStream bos = null; MultipartFile file = null ; InputStream inputStream = null ; try { PdfReader reader = new PdfReader(templatePdfPath); // 将要生成的目标PDF文件名称 bos = new ByteArrayOutputStream(); // 使用中文字体 PdfStamper ps = new PdfStamper(reader, bos); String url = "/home/data/pdf_template/simfang.ttf"; BaseFont bf = BaseFont.createFont(url, BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); // 可能存在的问题:adober的版本不同造成中文不能显示,或者其他原因导致字体失效。该方法不是很稳妥 // BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(); // 取出报表模板中的所有字段 fontList.add(bf); AcroFields fields = ps.getAcroFields(); fields.setSubstitutionFonts(fontList); // 必须要调用这个,否则文档不会生成的 如果为false那么生成的PDF文件还能编辑,一定要设为true fillData(fields, data); ps.setFormFlattening(true); ps.close(); byte[] testFile = bos.toByteArray(); inputStream = new ByteArrayInputStream(testFile); try { file = new MockMultipartFile(generatePdf, generatePdf, ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream); } catch (IOException e) { log.error(e.getMessage()); } } catch (Exception e) { e.printStackTrace(); } finally { if(inputStream != null ){ try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } return file; } }
标签:段域,fields,bos,param,new,PDF,null,data,模板 From: https://www.cnblogs.com/LilLazy/p/17368734.html