生成带照片和文字的 PDF,可以用一个外层表格组织卡片,再在每张卡片里放图片和说明。排版之前先确定纸张、列数、字体与图片缩放规则,输出会比单纯把图片逐张追加更可控。
外层网格和内层卡片
早期 iText 的 com.lowagie API 可以用 PdfPTable 嵌套表格。下面是布局片段,需要已有的 Document、可用字体 font 和图片路径列表 imagePaths:
int columns = 4;
PdfPTable grid = new PdfPTable(columns);
grid.setWidthPercentage(100);
for (String path : imagePaths) {
PdfPTable card = new PdfPTable(1);
Image image = Image.getInstance(path);
image.scaleToFit(100, 100);
card.addCell(image);
card.addCell(new Paragraph("照片说明", font));
grid.addCell(card);
}
int padding = (columns - imagePaths.size() % columns) % columns;
for (int i = 0; i < padding; i++) {
grid.addCell(" ");
}
document.add(grid);
补齐单元格的数量使用两次取余,避免图片数刚好整除列数时,又多生成一整行空白。卡片内容也可以增加姓名、地点等字段,但要确认换行和过长文字的分页效果。
中文字体与图片都要显式处理
选择实际存在且允许按用途使用的字体,按需要嵌入,使其他机器打开时也能显示中文。字体文件路径不应固定为某台 Windows 的系统目录;缺字与字体未嵌入是两个不同问题。
缩放图片时保持宽高比例。原始图片太大会增加 PDF 体积和处理内存,显示尺寸很小也不等于文件里的图像数据已变小。
资源和结果检查
按对应库版本关闭 Document、PdfWriter 和输出流,异常时不要对尚未初始化的对象直接 close。只有最终输出关闭完成,才能认定文件已写好。
com.lowagie、com.itextpdf 与后续 iText API 不能混合导入,示例需要配合自己的依赖版本。生成后验证零张、一张、刚好四张与五张图片,以及长文字和中文缺字,检查是否漏掉最后一行、是否多出空白页。
相关应用:PDF 合并工具。