依赖文件:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
创建PDF文件
public PdfReader getPdfBytes(Element element) {
if (element == null) {
return null;
}
Document document = new Document();
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, bos);
writer.setFullCompression();
writer.setCompressionLevel(PdfStream.BEST_COMPRESSION);
document.open();
document.add(element);
document.close();
writer.close();
return new PdfReader(bos.toByteArray());
} catch (Exception e) {
logger.error("getPdfBytes error", e);
}
return null;
}
public PdfPTable getUserTableInfo(List<UserDataVo> data) {
PdfPTable table = new PdfPTable(3);
table.setWidthPercentage(100);
float width = PageSize.A4.getWidth() - 40;
float dataWidth = width / 4;
float[] columnWidth = new float[] { dataWidth, dataWidth, dataWidth * 2};
try {
table.setTotalWidth(columnWidth);
} catch (Exception e) {
table.setTotalWidth(width);
}
table.addCell(getPdfCellInfo("ID"));
table.addCell(getPdfCellInfo("用户"));
table.addCell(getPdfCellInfo("简介"));
if (CollectionUtils.isNotEmpty(data)) {
data.stream().forEach(col -> {
table.addCell(getPdfCellInfo(col.getId()));
table.addCell(getPdfCellInfo(col.getUserName()));
table.addCell(getPdfCellInfo(col.getUserText()));
});
}
return table;
}
private PdfPCell getPdfCellInfo(String name) {
return getPdfCellInfo(name, 1);
}
private PdfPCell getPdfCellInfo(String name, int rowSpan) {
Font font = getBaseFontInstance();
PdfPCell cell = new PdfPCell(new Paragraph(StringUtils.defaultString(name), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
if (rowSpan > 1) {
cell.setRowspan(rowSpan);
}
return cell;
}
public static Font getBaseFontInstance() {
if (baseFont == null) {
baseFont = getPdfFont();
}
return baseFont;
}
private static Font getPdfFont() {
try {
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
BaseFont.NOT_EMBEDDED);
return new Font(bf, 10);
} catch (Exception e) {
return null;
}
}
合并pdf
public byte[] createAndMergeBlobPdf(List<PdfReader> readers) {
if (CollectionUtils.isEmpty(readers)) {
return null;
}
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Document document = new Document();
if (CollectionUtils.isNotEmpty(readers)) {
PdfCopy copy = new PdfCopy(document, bos);
copy.setFullCompression();
copy.setCompressionLevel(PdfStream.BEST_COMPRESSION);
document.open();
for (PdfReader reader: readers) {
if (reader != null) {
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
reader.close();
}
}
document.close();
copy.close();
}
return bos.toByteArray();
} catch (Exception e) {
logger.error("createAndMergeBlobPdf error", e);
}
return null;
}
优化:PdfCopy 更换为PdfSmartCopy,能压缩一半的大小
- PdfCopy:它会存储两个不同的图片流对象,在索引表中会引用两次,因此虽然是一个相同的图片,但是在不同的页面上会分别显示对应的图片。
- PdfSmartCopy:经过它处理,会重建索引表,会把这个图片流对象引用到不同的页面上,而这个图片对象只存储了一份。
PdfCopy处理比较快,但生成的文件的大小会很大,PdfSmartCopy比较慢,会消耗更多内存,但文件大小会很小。