需求
1.企业报告以pdf文档格式生成,多个pdf报告的合并以及图片添加到生成的pdf中。
前期准备
1.方案一:基于itext5 进行pdf生成(注意itext7 api 区别较大,尤其在于pdf合并处) 2.方案二:基于jasperreport生成(jasperreport studio 先画pdf表格,生成jasper.xml文件结合java生成pdf,但是此方案注重纯表格pdf样式定制,表格嵌套遍历缺乏灵活性。)
实战
一、itext5
1.gradle依赖配置
implementation 'com.itextpdf:itextpdf:5.5.13.1'
implementation 'com.lowagie:itext:2.1.7.js7'
compile group: 'net.sourceforge.barbecue', name: 'barbecue', version: '1.5-beta1'
2.解决中文不显示问题
- 2.1 下载所需字体放在resource目录下
- 2.2 配置字体
private static final String FONT = "fonts/msyh.ttf";
private Font font = new Font(BaseFont.createFont(FONT,
BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 16, 1);
3.生成PDF报告
- 3.1 定义document格式及输出的pdf名和输出位置
Document document = new Document(PageSize.A4, 50f, 50f, 70f, 50f);
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(test.pdf"));
- 3.2 Chunk
Chunk chunk= new Chunk("test", font);
- 3.3 Paragraph(行,独占一行)
Paragraph paragraph = new Paragraph("test", font);
paragraph.setAlignment(10); //居中
paragraph.setLeading(10); //行距
paragraph.setIndentationLeft(10); //缩进
paragraph.setFirstLineIndent(10);//首行缩进
- 3.4 Table
PdfPTable table = new PdfPTable(6); 6列
int itemHeaderWidths[] = {25, 15, 15, 15, 15, 15};// 每列宽度百分比
table.setWidths(itemHeaderWidths);
table.setWidthPercentage(100); //每列宽度按照百分比设置
table.addCell(phraseCell(cell1, 1, font)) //表格每列单元格数据添加
private PdfPCell phraseCell(String value, Integer colspan, Font font) {
PdfPCell pdfPCell = new PdfPCell(new Phrase(value, font));
pdfPCell.setHorizontalAlignment(ALIGN_LEFT);
pdfPCell.setHorizontalAlignment(ALIGN_BOTTOM);
pdfPCell.setMinimumHeight(23);//单元格高度
pdfPCell.setColspan(colspan);//合并单元格
return pdfPCell;
}
- 3.5 换行
document.add(Chunk.NEWLINE);
- 3.6 下划线
Paragraph paragraph = new Paragraph();
LineSeparator UNDERLINE = new LineSeparator(1, 100, null, Element.ALIGN_CENTER, -2);
paragraph.add(UNDERLINE);
- 3.7 另起一页
document.newPage();
- 3.8 给每一页添加页脚
- 注意: addFooter(pdfWriter)添加页脚方法必须放在 document.open() 之前否则页脚只在最后一页显示有
addFooter(pdfWriter);
private void addFooter(PdfWriter pdfWriter) throws Exception {
FooterPageEvent footerPageEvent = new FooterPageEvent();
pdfWriter.setPageEvent(footerPageEvent);
}
public class FooterPageEvent extends PdfPageEventHelper {
private static final String FONT = "fonts/msyh.ttf";
private BaseFont bf;
private Font contentFont;
public FooterPageEvent() throws IOException, DocumentException {
this.bf = BaseFont.createFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
this.contentFont = new Font(bf, 10);
}
@SneakyThrows
public void onEndPage(PdfWriter writer, Document document) {
PdfContentByte headAndFootPdfContent = writer.getDirectContent();
Phrase footer = new Phrase( "第" + writer.getCurrentPageNumber() + “页”, contentFont);
ColumnText.showTextAligned(headAndFootPdfContent ,
Element.ALIGN_CENTER,
footer,
(document.right() - document.left()) / 2 + document.leftMargin(),
document.bottom() - 10, 0);
}
}
- 3.9 计算pdf总页数 参考:my.oschina.net/u/3183495/b…
4.pdf添加图片
private void addImage(Document document, String imageUrl) throws Exception {
Resource resource = new FileSystemResource(imageUrl);
Image img = Image.getInstance(Paths.get(resource.getURI()).toAbsolutePath().toString());
if (img.getWidth() > img.getHeight())
img.setRotationDegrees(90);//如果图片宽度小于高度则竖着显示
img.scalePercent(65);//等比例缩放
document.add(img);
}
5.合并其他pdf
String first= "C://desktop//pdf//first.pdf";
String second= "C://desktop//pdf//second.pdf";
PdfCopy copy = new PdfCopy(document, new FileOutputStream("merged.pdf"));//合并后的pdf
document.open();
copyPdf(first, copy);
copyPdf(second, copy);
document.close();
private void copyPdf(String location, PdfCopy copy){
PdfReader reader = new PdfReader(first);
copy.addDocument(reader);
}