场景:我们经常会需要用代码生成pdf文件,涉及到复杂的内容也可以选用先自己制作pdf模板,再用代码去读取,动态数据部分的内容无法用模板实现的就要用Java代码去实现

需求:生成如下的pdf

Java向pdf模板中写入数据并在模板之后添加新的表格内容

Java向pdf模板中写入数据并在模板之后添加新的表格内容

实现思路:第一张表格内容看起来复杂一点可以用pdf模板,设置form域来存放需要填入的数据,后面的表格数据量不确定的就                 是要代码生成pdf方法去实现。

注意:由于读取了模板写入数据之后再用document.add()方法添加代码生成的表格内容无法生效(具体原因目前不知),如果先添加表格再写入模板数据的话,模板的form域会丢失无法再写入数据。因此我使用的方案是先读取模板写入数据后生成一个临时pdf,然后再去读取这个pdf并向它添加表格生成最终的pdf。

实现代码:

//baselineData后面表格中需要的数据

public static void downloadCreateListPdf( BaselineBO baselineData) throws Exception {

//模板内所需要的数据(测试数据)

              HashMap<String, String> map = new HashMap<String, String>();

                map.put("0", “0”);
        map.put("1", “1”);
        map.put("2", “2”);

map.put("3", “3”);

                map.put("4", “4”);
map.put("5", “5”);

map.put("6", “6”);

                map.put("7", “7”);

                map.put("8", “8”);
map.put("9", “9”);

map.put("10", “10”);

                map.put("11", “11”);

String ret = "D:\\file\\baseline.pdf";//pdf模板
String newPath = "D:\\file\\BaselineContent.pdf";
// 1.读取pdf模板并写入数据
writePdfModel(ret, newPath, templateMap);
String finalPath = "D:\\file\\baselineCreate.pdf";//最终模板生成路径
String type = "create";
generateFinalPdf(newPath, finalPath, type, baselineData);

}

//向模板中写入数据

private static void writePdfModel(String inPath, String outPath, HashMap<String, String> templateMap)
throws Exception {
FileOutputStream outputStream = new FileOutputStream(outPath);
PdfReader reader1 = new PdfReader(inPath);// 读取pdf模板
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader1, bos);
AcroFields form = stamper.getAcroFields();//获取form域
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
form.addSubstitutionFont(bfChinese);
Iterator<String> iterator = form.getFields().keySet().iterator();
int i = 0;
while (iterator.hasNext()) {
String name = iterator.next();
String key = String.valueOf(i);//form域我设置名称为0-11,方便循环set值
form.setField(name, templateMap.get(key));
i++;
}
stamper.setFormFlattening(true);
stamper.close();
outputStream.write(bos.toByteArray());
outputStream.flush();
outputStream.close();
bos.close();

}

/**
* 生成最终版本的pdf
* @param newPath 已写入数据的pdf模板路径
* @param finalPath 最终版本的pdf生成路径
* @param baselineData2 
* @throws Exception
*/
private static void generateFinalPdf(String newPath, String finalPath, String baselineType, BaselineBO baselineData) throws Exception {
FileOutputStream outputStream = new FileOutputStream(finalPath);
PdfReader reader = new PdfReader(newPath);// 读取pdf模板
Rectangle pageSize = reader.getPageSize(1);
Document document = new Document(pageSize);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
PdfContentByte cbUnder = writer.getDirectContentUnder();
PdfImportedPage pageTemplate = writer.getImportedPage(reader, 1);
cbUnder.addTemplate(pageTemplate, 0, 0);
document.newPage();//新创建一页来存放后面生成的表格
if ("create".equals(baselineType)) {
Paragraph paragraph = generatePdfATATable(baselineData);//此处为生成的表格及内容方法,只已ATA表为例,其余两个就不写了
//Paragraph paragraphFile = generatePdfFileTable(baselineData);
//Paragraph paragraphDM = generatePdfDMTable(baselineData);
document.add(paragraph);
//document.add(paragraphFile);
//document.add(paragraphDM);

document.close();
reader.close();

}

/**
* 生成pdf表格
* @return
* @see
*/
private static Paragraph generatePdfATATable(BaselineBO baselineData) throws Exception {
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font fontChinese = new Font(bfChinese, 10.5F, Font.NORMAL);// 五号
Paragraph ret = new Paragraph("附表1: 基线按ATA章节分类情况统计表", fontChinese);
PdfPTable tableBox = new PdfPTable(3);
tableBox.setWidths(new float[] { 0.3f, 0.4f, 0.3f });// 每个单元格占多宽
tableBox.setWidthPercentage(80f);
// 获取ATA分类的结果集
List<BaselineATA> ataList = countFileOrDMByATA(baselineData);
// 创建表格格式及内容
tableBox.addCell(getCell(new Phrase("基线按ATA章节分类情况", fontChinese), false, 3, 1));
tableBox.addCell(getCell(new Phrase("ATA", fontChinese), false, 1, 1));
tableBox.addCell(getCell(new Phrase("文件/图样数量", fontChinese), false, 1, 1));
tableBox.addCell(getCell(new Phrase("DM数量", fontChinese), false, 1, 1));
// 遍历查询出的结果
for (BaselineATA ata : ataList) {
tableBox.addCell(getCell(new Phrase(ata.getAta(), fontChinese), false, 1, 1));
tableBox.addCell(getCell(new Phrase(String.valueOf(ata.getFileNumber()), fontChinese), false, 1, 1));
tableBox.addCell(getCell(new Phrase(String.valueOf(ata.getDMNumber()), fontChinese), false, 1, 1));
}
ret.add(tableBox);
return ret;

}

//每个cell的格式,合并单元格情况

private static PdfPCell getCell(Phrase phrase, boolean yellowFlag, int colSpan, int rowSpan) {
PdfPCell cells = new PdfPCell(phrase);
cells.setUseAscender(true);
cells.setMinimumHeight(20f);
cells.setHorizontalAlignment(1);
cells.setVerticalAlignment(5);
cells.setColspan(colSpan);
cells.setRowspan(rowSpan);
cells.setNoWrap(false);
return cells;
}


相关文章:

  • 2021-08-01
  • 2021-08-15
  • 2022-12-23
  • 2022-02-16
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-18
猜你喜欢
  • 2022-12-23
  • 2022-01-19
  • 2022-12-23
  • 2022-12-23
  • 2022-02-09
  • 2022-12-23
  • 2021-11-04
相关资源
相似解决方案