Documento in scala Java iText in A4
Ho il seguente metodo che "ridimensiona" tutte le pagine di un documento alle dimensioni della pagina 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");
}
}
Tuttavia, questo non funziona come previsto, le pagine vengono trasformate in A4 (297x210) MA il contenuto non viene adattato all'interno (ridimensionato), il contenuto appare tagliato perché le pagine originali sono più grandi di 297X210. Come posso risolvere questo problema?
Risposte
In un commento hai chiarito
Voglio che il riquadro di delimitazione del contenuto precedente venga ridimensionato e venga aggiunto un margine nel target
Quindi, dobbiamo prima determinare il riquadro di delimitazione del contenuto della pagina originale. Questo può essere fatto usando la MarginFinderclasse da questa risposta . Attenzione: quella classe determina il riquadro di delimitazione di tutto il contenuto, anche se è semplicemente un rettangolo bianco visivamente non distinto da nessun contenuto o qualcosa che in precedenza era al di fuori del riquadro di ritaglio ... Se il tuo caso d'uso lo richiede, potresti dover estendere quella classe prendere in considerazione anche tali circostanze.
Con il riquadro di delimitazione del contenuto determinato, tutto ciò che resta da fare è un po 'di calcolo.
Il metodo seguente determina il riquadro di delimitazione utilizzando la classe precedente, trasforma il contenuto di conseguenza e modifica il riquadro di ritaglio del risultato.
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);
}
}
( Metodo ScaleToA4scale
)
Per una dimensione della pagina dei risultati A4 con un pollice di margine su ciascun lato, puoi chiamarla in questo modo per PdfDocument pdfDocument
:
Rectangle pageSize = PageSize.A4;
Rectangle pageBodySize = pageSize.clone().applyMargins(72, 72, 72, 72, false);
scale(pdfDocument, pageSize, pageBodySize);
(estratto dal test ScaleToA4testFdaRequiresUseOfEctdFormatAndStandardizedStudyDataInFutureRegulatorySubmissionsSept
)