Tài liệu Java iText quy mô thành A4

Aug 20 2020

Tôi có phương pháp sau "thay đổi kích thước" tất cả các trang của tài liệu thành kích thước trang 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");
        }
    }

Tuy nhiên, điều này không hoạt động như mong đợi, các trang đang được chuyển thành A4 (297x210) NHƯNG nội dung không được lắp vào bên trong (được thu nhỏ), nội dung có vẻ bị cắt vì các trang gốc lớn hơn 297X210. Làm thế nào tôi có thể sửa lỗi này ?

Trả lời

1 mkl Aug 24 2020 at 13:47

Trong một nhận xét bạn đã làm rõ

Tôi muốn hộp giới hạn của nội dung cũ được thu nhỏ và thêm một lề vào mục tiêu

Vì vậy, trước tiên chúng ta phải xác định hộp giới hạn của nội dung trang gốc. Điều này có thể được thực hiện bằng cách sử dụng MarginFinderlớp từ câu trả lời này . Lưu ý: Lớp đó xác định hộp giới hạn của tất cả nội dung, ngay cả khi nó chỉ là một hình chữ nhật màu trắng về mặt trực quan không khác biệt với không có nội dung nào hoặc thứ gì đó trước đây nằm ngoài hộp cắt ... Nếu trường hợp sử dụng của bạn yêu cầu, bạn có thể phải mở rộng lớp đó để xem xét những trường hợp như vậy.

Với hộp giới hạn nội dung, tất cả những gì còn lại phải làm là một chút tính toán.

Phương thức sau xác định hộp giới hạn bằng cách sử dụng lớp trên, biến đổi nội dung cho phù hợp và thay đổi hộp cắt kết quả.

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);
    }
}

( Phương pháp ScaleToA4scale )

Đối với kích thước trang kết quả A4 với một inch lề mỗi bên, bạn có thể gọi nó như thế này cho PdfDocument pdfDocument:

Rectangle pageSize = PageSize.A4;
Rectangle pageBodySize = pageSize.clone().applyMargins(72, 72, 72, 72, false);
scale(pdfDocument, pageSize, pageBodySize);

(trích từ bài kiểm tra ScaleToA4testFdaRequiresUseOfEctdFormatAndStandardizedStudyDataInFutureRegulatorySubmissionsSept )