java 生成有模板表单域的 PDF
1- 准备PDF域 数据
1 public void createNewPDFModel(String rid, String mid, JSONArray array, Map<String, Object> resultMap) throws DocumentException, IOException { 2 // TODO 自动生成的方法存根 3 Match match=matchMapper.selectByPrimaryKey(mid);//赛事信息 4 Race race=raceMapper.selectByPrimaryKey(rid);//赛项信息 5 List<Map<String,Object>> cupList = raceTeamScoreMapper.findCupListByMidRid(mid,rid);//奖杯 6 List<Map<String,Object>> awardsList = raceTeamScoreMapper.findAwardsListByMidRid(mid,rid);//奖项 7 List<Map<String,Object>> entryList = raceTeamScoreMapper.findEntryListByMidRid(mid,rid);//参赛证明 8 9 String mname = removeUnlawfulFileName(match.getMname()); 10 String rname = removeUnlawfulFileName(race.getRname()); 11 //奖励证书 12 String wordModelPathCup = match.getCupmodel().replace(MyProperties.getKey("RootFileUrlkey"), MyProperties.getKey("RootPathkey")); 13 //wordModelPathCup="D:/pdf/奖励证书模板V4.0表单.pdf"; 14 for(Map<String,Object> map:cupList){ 15 String tname =removeUnlawfulFileName((String) map.get("tname")); 16 String savePdfPath = MyProperties.getKey("RootPathkey")+"pdf/"+mname+"/"+rname+"/奖励证书/"+mname+rname+tname+"奖励证书.pdf"; 17 String url = MyProperties.getKey("RootFileUrlkey")+"pdf/"+mname+"/"+rname+"/奖励证书/"+mname+rname+tname+"奖励证书.pdf"; 18 File file = new File(savePdfPath); 19 if (!file.exists()) { 20 // 如果路径不存在,则创建 21 file.getParentFile().mkdirs(); 22 } 23 Map<String, String> dataParamMap = new HashMap<String, String>(); 24 dataParamMap.put("编号", (String) map.get("cupno")); 25 26 // String name = (String) map.get("school")+" \n\r "+(String) map.get("tname"); 27 dataParamMap.put("学校", (String) map.get("school")); 28 dataParamMap.put("队伍", (String) map.get("tname")); 29 // dataParamMap.put("学校队伍", name); 30 31 dataParamMap.put("小项", (String) map.get("rname")); 32 dataParamMap.put("奖杯", (String) map.get("cup")); 33 dataParamMap.put("教师",(String) map.get("teachers")); 34 dataParamMap.put("队员",(String) map.get("students")); 35 36 PdfModeForPdf.formFdfModeForPdf(dataParamMap, savePdfPath, wordModelPathCup); 37 38 39 RaceTeamScore raceTeamScore = new RaceTeamScore(); 40 raceTeamScore.setTid((String) map.get("tid")); 41 raceTeamScore.setRid((String) map.get("rid")); 42 raceTeamScore.setCupurl(url); 43 raceTeamScore.setCreatstatus("00"); 44 raceTeamScoreMapper.updateByPrimaryKeySelective(raceTeamScore); 45 46 } 47 48 String zipFilePath = MyProperties.getKey("RootPathkey")+"zip/"+mname+"/"+rname+"/"; 49 File file = new File(zipFilePath); 50 if (!file.exists()) { 51 // 如果路径不存在,则创建 52 file.mkdirs(); 53 } 54 55 sourceFilePath = MyProperties.getKey("RootPathkey")+"pdf/"+mname+"/"+rname+"/奖励证书"; 56 fileName = mname+rname+"奖励证书ZIP"; 57 FileToZip.fileToZip(sourceFilePath, zipFilePath, fileName); 58 59 System.out.println("全部生成完毕"); 60 resultMap.put("status", 0); 61 }
2- 绘制PDF
1 package com.zts.robot.util; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.util.List; 7 import java.util.Map; 8 9 import com.itextpdf.text.Chunk; 10 import com.itextpdf.text.Document; 11 import com.itextpdf.text.DocumentException; 12 import com.itextpdf.text.Element; 13 import com.itextpdf.text.Font; 14 import com.itextpdf.text.Paragraph; 15 import com.itextpdf.text.Rectangle; 16 import com.itextpdf.text.pdf.AcroFields; 17 import com.itextpdf.text.pdf.BaseFont; 18 import com.itextpdf.text.pdf.PdfContentByte; 19 import com.itextpdf.text.pdf.PdfCopy; 20 import com.itextpdf.text.pdf.PdfImportedPage; 21 import com.itextpdf.text.pdf.PdfPCell; 22 import com.itextpdf.text.pdf.PdfPTable; 23 import com.itextpdf.text.pdf.PdfReader; 24 import com.itextpdf.text.pdf.PdfStamper; 25 26 public class PdfModeForPdf { 27 public static void formFdfModeForPdf(Map<String, String> dataParamMap, String savePdfPath, 28 String wordModelPathCup) throws DocumentException, IOException { 29 30 BaseFont simheiChinese = BaseFont.createFont(MyProperties.getKey("simhei"),BaseFont.IDENTITY_H,BaseFont.EMBEDDED); 31 32 PdfReader reader; 33 FileOutputStream out; 34 ByteArrayOutputStream bos; 35 PdfStamper stamper; 36 37 out = new FileOutputStream(savePdfPath);// 输出流 38 reader = new PdfReader(wordModelPathCup);// 读取pdf模板 39 bos = new ByteArrayOutputStream(); 40 stamper = new PdfStamper(reader, bos); 41 AcroFields form = stamper.getAcroFields(); 42 43 PdfContentByte pcb = stamper.getOverContent(1); 44 //获取表单域坐标 45 List<AcroFields.FieldPosition> list = form.getFieldPositions("成员"); 46 Rectangle rect = list.get(0).position; 47 //创建PDF表格 48 PdfPTable table = new PdfPTable(2); 49 float tatalWidth = rect.getRight() - rect.getLeft() - 1; 50 //计算表格宽度 51 float[] columnWidth ={(float) (tatalWidth*0.17),(float)(tatalWidth*0.83)}; 52 table.setTotalWidth(columnWidth); 53 54 Font FontProve = new Font(simheiChinese, 15, 0); 55 Paragraph p11 = new Paragraph("指导教师:", FontProve); 56 Paragraph p12 = new Paragraph((String) dataParamMap.get("教师"), FontProve); 57 Paragraph p21 = new Paragraph("队 员:", FontProve); 58 Paragraph p22 = new Paragraph((String) dataParamMap.get("队员"), FontProve); 59 60 PdfPCell cell11 = new PdfPCell(p11); 61 //cell11.setFixedHeight(rect.getTop() - rect.getBottom() - 1); 62 cell11.setBorderWidth(0); 63 cell11.setVerticalAlignment(Element.ALIGN_LEFT); 64 cell11.setHorizontalAlignment(Element.ALIGN_LEFT); 65 cell11.setLeading(0, (float) 1.4); 66 table.addCell(cell11); 67 68 PdfPCell cell12 = new PdfPCell(p12); 69 //cell12.setFixedHeight(rect.getTop() - rect.getBottom() - 1); 70 cell12.setBorderWidth(0); 71 cell12.setVerticalAlignment(Element.ALIGN_LEFT); 72 cell12.setHorizontalAlignment(Element.ALIGN_LEFT); 73 cell12.setLeading(0, (float) 1.4); 74 table.addCell(cell12); 75 76 PdfPCell cell21 = new PdfPCell(p21); 77 //cell11.setFixedHeight(rect.getTop() - rect.getBottom() - 1); 78 cell21.setBorderWidth(0); 79 cell21.setVerticalAlignment(Element.ALIGN_LEFT); 80 cell21.setHorizontalAlignment(Element.ALIGN_LEFT); 81 cell21.setLeading(0, (float) 1.4); 82 table.addCell(cell21); 83 84 PdfPCell cell22 = new PdfPCell(p22); 85 //cell12.setFixedHeight(rect.getTop() - rect.getBottom() - 1); 86 cell22.setBorderWidth(0); 87 cell22.setVerticalAlignment(Element.ALIGN_LEFT); 88 cell22.setHorizontalAlignment(Element.ALIGN_LEFT); 89 cell22.setLeading(0, (float) 1.4); 90 table.addCell(cell22); 91 92 table.writeSelectedRows(0, -1, rect.getLeft(), rect.getTop(), pcb); 93 94 // for (String key : dataParamMap.keySet()) { 95 // form.setField(key,dataParamMap.get(key).toString()); 96 // } 97 98 for (String key : dataParamMap.keySet()) { 99 int ilen = dataParamMap.get(key).toString().length(); 100 if(key == "学校" || key == "队伍"){ 101 if(ilen >= 20 && ilen < 40){ 102 form.setFieldProperty(key, "textsize", new Float(10), null); 103 }else if(ilen >= 40 && ilen <= 55){ 104 form.setFieldProperty(key, "textsize", new Float(7), null); 105 }else if(ilen > 55){ 106 form.setFieldProperty(key, "textsize", new Float(6), null); 107 } 108 } 109 110 form.setField(key,dataParamMap.get(key).toString()); 111 } 112 113 form.setField("成员", ""); 114 stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true 115 stamper.close(); 116 117 Document doc = new Document(); 118 PdfCopy copy = new PdfCopy(doc, out); 119 doc.open(); 120 PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1); 121 copy.addPage(importPage); 122 doc.close(); 123 124 } 125 126 public static void replaceFormFdfModeForPdf(Map<String, String> dataParamMap, String savePdfPath, 127 String wordModelPathCup) throws DocumentException, IOException { 128 129 BaseFont fzcsjtChinese = BaseFont.createFont(MyProperties.getKey("fzcs"),BaseFont.IDENTITY_H,BaseFont.EMBEDDED); 130 PdfReader reader; 131 FileOutputStream out; 132 ByteArrayOutputStream bos; 133 PdfStamper stamper; 134 135 out = new FileOutputStream(savePdfPath);// 输出流 136 reader = new PdfReader(wordModelPathCup);// 读取pdf模板 137 bos = new ByteArrayOutputStream(); 138 stamper = new PdfStamper(reader, bos); 139 AcroFields form = stamper.getAcroFields(); 140 PdfContentByte pcb = stamper.getOverContent(1); 141 142 String prove = form.getField("证明"); 143 //获取表单域坐标 144 List<AcroFields.FieldPosition> list = form.getFieldPositions("证明"); 145 Rectangle rect = list.get(0).position; 146 //创建PDF表格 147 PdfPTable table = new PdfPTable(1); 148 float tatalWidth = rect.getRight() - rect.getLeft() - 1; 149 //计算表格宽度 150 table.setTotalWidth(tatalWidth); 151 Font FontProve = new Font(fzcsjtChinese, 18, 0); 152 Font FontProveUnderLine = new Font(fzcsjtChinese, 18,Font.UNDERLINE ); 153 Paragraph p1 = new Paragraph(); 154 int indexStart=0; 155 int indexEnd=0; 156 while(prove.length()>0){ 157 158 indexStart = prove.indexOf("<"); 159 indexEnd = prove.indexOf(">"); 160 if(indexStart==-1){ 161 p1.add(new Chunk(prove, FontProve)); 162 break; 163 }else{ 164 String key = prove.substring(indexStart+1, indexEnd); 165 String str = prove.substring(0,indexStart); 166 prove = prove.substring(indexEnd+1); 167 p1.add(new Chunk(str, FontProve)); 168 p1.add(new Chunk(dataParamMap.get(key), FontProveUnderLine)); 169 } 170 } 171 172 173 PdfPCell cell = new PdfPCell(p1); 174 cell.setFixedHeight(rect.getTop() - rect.getBottom() - 1); 175 cell.setBorderWidth(0); 176 cell.setVerticalAlignment(Element.ALIGN_LEFT); 177 cell.setHorizontalAlignment(Element.ALIGN_LEFT); 178 cell.setLeading(0, (float) 1.7); 179 table.addCell(cell); 180 table.writeSelectedRows(0, -1, rect.getLeft(), rect.getTop(), pcb); 181 182 form.setField("编号", dataParamMap.get("编号").toString()); 183 form.setField("证明", ""); 184 185 stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true 186 stamper.close(); 187 188 Document doc = new Document(); 189 PdfCopy copy = new PdfCopy(doc, out); 190 doc.open(); 191 PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1); 192 copy.addPage(importPage); 193 doc.close(); 194 195 } 196 }
有PDF模板的情况下,重新绘制PDF
1- 使用 Adobe Acrobat DC
2- 编辑PDF > 准备表单
代码中读取PDF模板,按照排版好的域,顺序写入内容
1 AcroFields form = stamper.getAcroFields();
for (String key : dataParamMap.keySet()) { int ilen = dataParamMap.get(key).toString().length(); if(key == "学校" || key == "队伍"){ if(ilen >= 20 && ilen < 40){ form.setFieldProperty(key, "textsize", new Float(10), null); }else if(ilen >= 40 && ilen <= 55){ form.setFieldProperty(key, "textsize", new Float(7), null); }else if(ilen > 55){ form.setFieldProperty(key, "textsize", new Float(6), null); } } form.setField(key,dataParamMap.get(key).toString()); }
reference:
https://itextpdf.com/