答案 0 :(得分:1)
此任务类似于this answer中实施的任务,拆分不仅仅是在一个维度而是在二维中。
因此,可以使用那里使用的AbstractPdfPageSplittingTool来实现可能的解决方案。
所以,我们再次有一个抽象的分裂器类
public abstract class Abstract2DPdfPageSplittingTool {
public void split(OutputStream outputStream, PdfReader... inputs) throws DocumentException, IOException {
try {
initDocument(outputStream);
for (PdfReader reader : inputs) {
split(reader);
}
} finally {
closeDocument();
}
}
void initDocument(OutputStream outputStream) throws DocumentException {
final Document document = new Document(PageSize.A4);
final PdfWriter writer = PdfWriter.getInstance(document, outputStream);
this.document = document;
this.writer = writer;
}
void closeDocument() {
try {
document.close();
} finally {
this.document = null;
this.writer = null;
}
}
void newPage(Rectangle pageSize) {
document.setPageSize(pageSize);
if (!document.isOpen())
document.open();
else
document.newPage();
}
void split(PdfReader reader) throws IOException {
for (int page = 1; page <= reader.getNumberOfPages(); page++) {
split(reader, page);
}
}
void split(PdfReader reader, int page) throws IOException
{
PdfImportedPage importedPage = writer.getImportedPage(reader, page);
Rectangle pageSizeToImport = reader.getPageSize(page);
Iterable<Rectangle> rectangles = determineSplitRectangles(reader, page);
for (Rectangle rectangle : rectangles) {
newPage(rectangle);
PdfContentByte directContent = writer.getDirectContent();
directContent.saveState();
directContent.rectangle(rectangle.getLeft(), rectangle.getBottom(), rectangle.getWidth(), rectangle.getHeight());
directContent.clip();
directContent.newPath();
writer.getDirectContent().addTemplate(importedPage, -pageSizeToImport.getLeft(), -pageSizeToImport.getBottom());
directContent.restoreState();
}
}
protected abstract Iterable<Rectangle> determineSplitRectangles(PdfReader reader, int page);
Document document = null;
PdfWriter writer = null;
}
(Abstract2DPdfPageSplittingTool.java)
此实用程序允许将每个源页面拆分为一组自定义结果页面,每个结果页面可以表示源页面的任意矩形(边缘平行于相应的页面边缘)。
您可以使用这样的工具沿A4单元网格分割页面:
Abstract2DPdfPageSplittingTool tool = new Abstract2DPdfPageSplittingTool() {
@Override
protected Iterable<Rectangle> determineSplitRectangles(PdfReader reader, int page) {
Rectangle targetSize = PageSize.A4;
List<Rectangle> rectangles = new ArrayList<>();
Rectangle pageSize = reader.getPageSize(page);
for (float y = pageSize.getTop(); y > pageSize.getBottom() + 5; y-=targetSize.getHeight()) {
for (float x = pageSize.getLeft(); x < pageSize.getRight() - 5; x+=targetSize.getWidth()) {
rectangles.add(new Rectangle(x, y - targetSize.getHeight(), x + targetSize.getWidth(), y));
}
}
return rectangles;
}
};
tool.split(RESULT_OUTPUT_STREAM, new PdfReader(SOURCE_PDF));
(基于SplitPages测试testSplitDocumentA6
)
由于纸张尺寸规格存在一定的容差,我会删除Rectangles
,它只包含左侧或顶部原始文档中的一个非常小的带,以防止出现空结果页,假设这些波段完全包含在原始页边距中。如果您不想要,请删除(或更改)示例+ 5
循环中的- 5
或determineSplitRectangles
。