分割pdf为模板
产品给了我一个pdf模板文件,里面有3个证书的模板,第1、2页是第一个证书的正反面,3、4页是另一个证书的正反面,第5页是个单页证书。为了在多人生成时降低IO开销,我奖模板按证书分割成多个pdf模板,按需加载。
/**
* 将pdf按页拆分组合,生成多个pdf
*/
PdfReader reader = new PdfReader("C:\\模板.pdf");
Document document1 = new Document(reader.getPageSize(1));
PdfCopy pdfCopy1 = new PdfCopy(document1, new FileOutputStream(new File("C:\\团队一等奖模板.pdf")));
document1.open();
document1.newPage();
PdfImportedPage page1zm = pdfCopy1.getImportedPage(reader, 1); // 正面
pdfCopy1.addPage(page1zm);
PdfImportedPage page1bm = pdfCopy1.getImportedPage(reader, 2); // 背面
pdfCopy1.addPage(page1bm);
document1.close();
Document document2 = new Document(reader.getPageSize(3));
PdfCopy pdfCopy2 = new PdfCopy(document2, new FileOutputStream(new File("C:\\团队二等奖模板.pdf")));
document2.open();
document2.newPage();
PdfImportedPage page2zm = pdfCopy2.getImportedPage(reader, 3); // 正面
pdfCopy2.addPage(page2zm);
PdfImportedPage page2bm = pdfCopy2.getImportedPage(reader, 4); // 背面
pdfCopy2.addPage(page2bm);
document2.close();
Document document3 = new Document(reader.getPageSize(5));
PdfCopy pdfCopy3 = new PdfCopy(document3, new FileOutputStream(new File("C:\\个人一等奖模板.pdf")));
document3.open();
document3.newPage();
PdfImportedPage page3zm = pdfCopy3.getImportedPage(reader, 5); // 正面
pdfCopy3.addPage(page3zm);
document3.close();
基于模板生成结果证书
模板在一些位置预留了空位,需要将文字信息填到空白处。
证书生成主要包含字体设置、文本坐标位置设置、公章png图片贴图等操作。
PdfReader reader = new PdfReader("C:\\团队一等奖模板.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("C:\\生成结果.pdf"));
// 证书正面
PdfContentByte zm = stamper.getOverContent(1);
// 在相应位置打上学校名称
BaseFont font = BaseFont.createFont("C:\\simkai.ttf", BaseFont.IDENTITY_H, true);
zm.setFontAndSize(font, 18);
zm.beginText();
// ALIGN_CENTER 以x、y作为中心点左右上下展开,确定好横线中心点坐标后能实现内容在横线内自动居中。
zm.showTextAligned(PdfContentByte.ALIGN_CENTER, "电子科技大学", 260,364, 0);
zm.endText();
// 在相应位置打上指导老师
zm.setFontAndSize(font, 18);
zm.beginText();
// ALIGN_LEFT 以x、y为起始点,向右边显示内容。 指导老师文本适合用这种方式。
zm.showTextAligned(PdfContentByte.ALIGN_LEFT, "陈XX、王XX", 232,152, 0);
zm.endText();
// 在相应位置贴上公章1图片
Image seal1 = com.lowagie.text.Image.getInstance("C:\\seal1.png");
seal1.setAbsolutePosition(420, 60);
seal1.scaleToFit(120, 120); // scaleToFit:在一个矩形内保持原图尺寸比例缩放,不超出矩形范围
zm.addImage(seal1);
// 在相应位置贴上公章2图片
Image seal2 = com.lowagie.text.Image.getInstance("C:\\seal2.png");
seal2.setAbsolutePosition(620, 60);
seal2.scaleToFit(120, 120); // scaleToFit:在一个矩形内保持原图尺寸比例缩放,不超出矩形范围
zm.addImage(seal2);
// 证书背面
PdfContentByte bm = stamper.getOverContent(2);
// 在相应位置打上团队成员名称
String teamMembers = "张三三、李四四、王五五、陈六六、赵七七";
font = BaseFont.createFont("C:\\simkai.ttf", BaseFont.IDENTITY_H, true);
bm.setFontAndSize(font, 16);
bm.beginText();
// 每行最多显示10个名字,超过则换行
List<String> names = Arrays.stream(teamMembers.split("、")).collect(Collectors.toList());
if (names.size() <= 10) {
String line1 = String.join("、", names.subList(0, names.size()));
bm.showTextAligned(PdfContentByte.ALIGN_CENTER, line1, 420,310, 0);
} else if (names.size() <= 20) {
String line1 = String.join("、", names.subList(0, 10));
bm.showTextAligned(PdfContentByte.ALIGN_CENTER, line1, 420,310, 0);
String line2 = String.join("、", names.subList(10, names.size()));
bm.showTextAligned(PdfContentByte.ALIGN_CENTER, line2, 420,280, 0);
} else if (names.size() <= 30) {
String line1 = String.join("、", names.subList(0, 10));
bm.showTextAligned(PdfContentByte.ALIGN_CENTER, line1, 420,310, 0);
String line2 = String.join("、", names.subList(10, 20));
bm.showTextAligned(PdfContentByte.ALIGN_CENTER, line2, 420,280, 0);
String line3 = String.join("、", names.subList(20, names.size()));
bm.showTextAligned(PdfContentByte.ALIGN_CENTER, line3, 420,250, 0);
}
bm.endText();
// 在相应位置贴上公章1图片
seal1.setAbsolutePosition(420, 60);
seal1.scaleToFit(120, 120); // 在一个矩形内保持原图尺寸比例缩放,不超出矩形范围
bm.addImage(seal1);
// 在相应位置贴上公章2图片
seal2.setAbsolutePosition(620, 60);
seal2.scaleToFit(120, 120); // 在一个矩形内保持原图尺寸比例缩放,不超出矩形范围
bm.addImage(seal2);
stamper.close();
reader.close();