问题描述
我有以下方法可以将文档的所有页面“调整大小”为A4页面尺寸:
for (PdfDocument doc : pdfDocuments) {
int n = doc.getNumberOfPages();
for (int i = 1; i <= n; i++) {
pdfpage page = doc.getPage(i);
Rectangle media = page.getCropBox();
if (media == null) {
media = page.getMediaBox();
}
Rectangle crop = new Rectangle(0,210,297);
page.setMediaBox(crop);
page.setCropBox(crop);
// The content,placed on a content stream before,will be rendered before the other content
// and,therefore,Could be understood as a background (bottom "layer")
new PdfCanvas(page.newContentStreamBefore(),page.getResources(),doc).writeLiteral("\nq 0.5 0 0 0.5 0 0 cm\nq\n");
// The content,placed on a content stream after,will be rendered after the other content
// and,Could be understood as a foreground (top "layer")
new PdfCanvas(page.newContentStreamAfter(),doc).writeLiteral("\nQ\nQ\n");
}
}
但是,这不能按预期方式工作,页面已转换为A4(297x210),但内容未放入内部(已缩放),由于原始页面大于297X210,内容似乎被剪切。我该如何解决?
解决方法
在您澄清的评论中
我希望缩放先前内容的边界框,并在目标中添加边距
因此,我们首先必须确定原始页面内容的边界框。可以使用MarginFinder
中的this answer类来完成。当心:该类确定 all 内容的边界框,即使它只是一个白色矩形,在视觉上与其他内容或裁切框之外的内容也没有区别……如果您的用例需要,您可能还必须扩展该类,以考虑到这种情况。
确定了内容边界框后,剩下要做的就是一点计算。
以下方法使用上面的类确定边界框,相应地转换内容,并更改结果裁剪框。
void scale(PdfDocument pdfDocument,Rectangle pageSize,Rectangle pageBodySize) {
int n = pdfDocument.getNumberOfPages();
for (int i = 1; i <= n; i++) {
PdfPage page = pdfDocument.getPage(i);
MarginFinder marginFinder = new MarginFinder();
PdfCanvasProcessor pdfCanvasProcessor = new PdfCanvasProcessor(marginFinder);
pdfCanvasProcessor.processPageContent(page);
Rectangle boundingBox = marginFinder.getBoundingBox();
if (boundingBox == null || boundingBox.getWidth() == 0 || boundingBox.getHeight() == 0) {
System.err.printf("Cannot scale page %d contents with bounding box %s\n",i,boundingBox);
continue;
} else {
// Scale and move content into A4 with margin
double scale = 0,xDiff= 0,yDiff = 0;
double xScale = pageBodySize.getWidth()/boundingBox.getWidth();
double yScale = pageBodySize.getHeight()/boundingBox.getHeight();
if (xScale < yScale) {
yDiff = boundingBox.getHeight() * (yScale / xScale - 1) / 2;
scale = xScale;
} else {
xDiff = boundingBox.getWidth() * (xScale / yScale - 1) / 2;
scale = yScale;
}
AffineTransform transform = AffineTransform.getTranslateInstance(pageBodySize.getLeft() + xDiff,pageBodySize.getBottom() + yDiff);
transform.scale(scale,scale);
transform.translate(-boundingBox.getLeft(),-boundingBox.getBottom());
new PdfCanvas(page.newContentStreamBefore(),page.getResources(),pdfDocument)
.concatMatrix(transform);
}
page.setMediaBox(pageSize);
page.setCropBox(pageSize);
}
}
(ScaleToA4方法scale
)
对于A4结果页面大小,每边都有一英寸的空白,您可以像这样PdfDocument pdfDocument
来称呼它:
Rectangle pageSize = PageSize.A4;
Rectangle pageBodySize = pageSize.clone().applyMargins(72,72,false);
scale(pdfDocument,pageSize,pageBodySize);
(摘录自ScaleToA4测试testFdaRequiresUseOfEctdFormatAndStandardizedStudyDataInFutureRegulatorySubmissionsSept
)