14 October 2009

生成带照片和文字的 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 合并工具。





blog comments powered by Disqus
Fork me on GitHub