Dokumen skala iText Java ke A4
Saya memiliki metode berikut yang "mengubah ukuran" semua halaman dokumen ke dimensi halaman 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, 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, therefore, could be understood as a foreground (top "layer")
new PdfCanvas(page.newContentStreamAfter(),
page.getResources(), doc).writeLiteral("\nQ\nQ\n");
}
}
Namun, ini tidak berfungsi seperti yang diharapkan, halaman sedang diubah menjadi A4 (297x210) TETAPI konten tidak dipasang di dalamnya (diskalakan), konten tampak terpotong karena halaman asli lebih besar dari 297X210. Bagaimana cara memperbaikinya?
Jawaban
Dalam komentar Anda mengklarifikasi
Saya ingin kotak pembatas dari konten sebelumnya diskalakan dan margin ditambahkan di target
Jadi, pertama-tama kita harus menentukan kotak pembatas dari konten halaman asli. Ini dapat dilakukan dengan menggunakan MarginFinderkelas dari jawaban ini . Hati-hati: Kelas tersebut menentukan kotak pembatas dari semua konten, meskipun itu hanya sebuah persegi panjang putih yang secara visual tidak berbeda dari tidak ada konten atau sesuatu yang sebelumnya berada di luar kotak potong ... Jika kasus penggunaan Anda memerlukannya, Anda mungkin harus memperluas kelas itu untuk mempertimbangkan keadaan seperti itu juga.
Dengan kotak pembatas konten ditentukan, yang perlu dilakukan hanyalah sedikit perhitungan.
Metode berikut menentukan kotak pembatas menggunakan kelas di atas, mengubah konten yang sesuai, dan mengubah kotak hasil krop.
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);
}
}
( Metode ScaleToA4scale
)
Untuk ukuran halaman hasil A4 dengan satu inci margin di setiap sisi Anda dapat menyebutnya seperti ini untuk PdfDocument pdfDocument
:
Rectangle pageSize = PageSize.A4;
Rectangle pageBodySize = pageSize.clone().applyMargins(72, 72, 72, 72, false);
scale(pdfDocument, pageSize, pageBodySize);
(kutipan dari tes ScaleToA4testFdaRequiresUseOfEctdFormatAndStandardizedStudyDataInFutureRegulatorySubmissionsSept
)