iText7 scaling rotated document with links

2019-09-02 08:28发布

问题:

I am using iText7(java) and trying to scale a portrait document to landscape. The document contains links and has rotation set to 270. Setting mediabox and cropbox on document does not work due to rotation. The solution mentioned in iText Examples does not work properly and hyperlinks in document stop working. There might be loss of other metadata as well .

Is there any way to scale the document without using copyAsFormXObject. Following method in itext7 to manipulate documents works very well for adding footers, watermarks , etc. Is there any way to scale document in following code ?

PdfDocument pdfDoc = new PdfDocument(new PdfReader(srcDoc), new PdfWriter(outPut));
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
    PdfPage page = pdfDoc.getPage(i);
    page.setIgnorePageRotationForContent(true);
    // change page scaling here
}
pdfDoc.close();

I have following working code to copy links and scale document to full width. Anyone can use following code if that is all they need.

boolean isLandscape = CommonConstants.LAYOUT_LANDSCAPE.equalsIgnoreCase(vo.getLayout());

ByteArrayOutputStream resizedPdfBytes = new ByteArrayOutputStream();
        PdfWriter pdfWriter = new PdfWriter(resizedPdfBytes);
        PdfReader pdfReader = new PdfReader(new ByteArrayInputStream(mergedPdfBytes.toByteArray()));
        PdfDocument writerDoc = new PdfDocument(pdfWriter);
        PdfDocument readerDoc = new PdfDocument(pdfReader);
        Rectangle targetSize = new Rectangle(PageSize.A4.getWidth(), PageSize.A4.getHeight());
        if(isLandscape){
             targetSize = new Rectangle(PageSize.A4.getHeight(), PageSize.A4.getWidth());
        }
        for (int i = 1; i <= readerDoc.getNumberOfPages(); i++) {
            PdfPage origPage = readerDoc.getPage(i);
            PdfPage page = writerDoc.addNewPage(new PageSize(targetSize));
            Rectangle orig = origPage.getPageSizeWithRotation();
            double heightScale = 1, widthScale = 1;
            widthScale = targetSize.getHeight() / orig.getHeight();
            heightScale = targetSize.getWidth() / orig.getWidth();              

            for (int k = 0; k < origPage.getAnnotsSize(); k++) {
                PdfAnnotation annotation = origPage.getAnnotations().get(k);
                PdfAnnotation annotation1 = new PdfLinkAnnotation(annotation.getPdfObject().copyTo(writerDoc));
                PdfArray array = new PdfArray();
                Rectangle oldArray = annotation.getRectangle().toRectangle();
                array.add(new PdfNumber(heightScale * oldArray.getLeft()));
                array.add(new PdfNumber(widthScale * oldArray.getTop()));
                array.add(new PdfNumber(heightScale * oldArray.getRight()));
                array.add(new PdfNumber(widthScale * oldArray.getBottom()));
                annotation1.setRectangle(array);
                page.addAnnotation(annotation1);
            }

            PdfCanvas canvas = new PdfCanvas(page);

            AffineTransform transformationMatrix = AffineTransform.getScaleInstance(heightScale, widthScale);
            canvas.concatMatrix(transformationMatrix);
            PdfFormXObject pageCopy = origPage.copyAsFormXObject(writerDoc);
            canvas.addXObject(pageCopy, 0, 0);
        }

        writerDoc.close();
        readerDoc.close();

This feels quite similar to itext2, I hope there is a better way to do this.