如何在itext7 C#中将页面大小从A3缩放到A4?

问题描述 投票:0回答:2

我尝试将 HTML 转换为 A4 页面大小的 PDF。但内容太长,PDF 分成了 2 页。我只想把它写进一页。所以我的想法是转换为A3尺寸的PDF,然后缩小到A4尺寸。 但另一个问题是从 A3 页面尺寸缩小到 A4 页面尺寸。

c# itext7
2个回答
3
投票

1) 将 html 转换为 A3 大小的文档

2)遍历页面并将每个页面复制为 formXObject

3)对于每个页面formXObject:

a) 用 0.5 系数缩放;

b) 添加到生成的文档中。

合适的Java代码如下(移植到C#应该没有问题,因为iText的API是一样的):

    // 1
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(baos));
    pdfDocument.setDefaultPageSize(PageSize.A3);
    HtmlConverter.convertToPdf(new FileInputStream(sourcePath), pdfDocument);

    PdfDocument resultantDocument = new PdfDocument(new PdfWriter(destPath));

    pdfDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())));
    // 2
    for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
        PdfPage page = pdfDocument.getPage(i);
        PdfFormXObject formXObject = page.copyAsFormXObject(resultantDocument);
        PdfCanvas pdfCanvas = new PdfCanvas(resultantDocument.addNewPage());
        // 3a and 3b
        pdfCanvas.addXObject(formXObject, 0.5f, 0, 0, 0.5f, 0, 0);
    }

    pdfDocument.close();
    resultantDocument.close();

0
投票

我的目标是将每一页都以纵向和 A4 格式放置。有时高度和宽度会翻转,所以也必须检查一下。最终,注释也没有缩放。想出了这个代码来完成这三个任务。

请参阅

ScalePageToA4
了解如何缩放每个页面。请记住,页面不是零索引。

//argument documents: byte[]?
MemoryStream readStream = new(documents);
MemoryStream writeStream = new();

try
{
    var reader = new PdfReader(readStream);
    var writer = new PdfWriter(writeStream);
    PdfDocument pdf = new(reader, writer);
    int numberOfPages = pdf.GetNumberOfPages();

    for (int i = 1; i <= numberOfPages; i++)
    {
        PdfPage page = pdf.GetPage(i);

        if (IsLandscape(page))
        {
            page.SetRotation((page.GetRotation() + 90) % 360);
        }

        ScalePageToA4(pdf, page);
    }

    pdf.Close();
    return writeStream.ToArray();

}
finally
{
    readStream?.Close();
    readStream?.Dispose();
    writeStream?.Close();
    writeStream?.Dispose();
}
private static bool IsLandscape(PdfPage page)
{
    Rectangle pageSize = page.GetPageSizeWithRotation();
    float originalWidth = pageSize.GetWidth();
    float originalHeight = pageSize.GetHeight();
    return originalWidth > originalHeight;
}
private static void ScalePageToA4(PdfDocument pdf, PdfPage page)
{
    const float A4_WIDTH = 842;
    const float A4_HEIGHT = 595;

    Rectangle media = page.GetCropBox() ?? page.GetMediaBox();

    Rectangle crop = new(0, 0, A4_WIDTH, A4_HEIGHT);
    double scaleX = A4_WIDTH / media.GetWidth();
    double scaleY = A4_HEIGHT / media.GetHeight();

    if (media.GetWidth() == page.GetPageSizeWithRotation().GetWidth())
    {
        crop = new(0, 0, A4_HEIGHT, A4_WIDTH);
        scaleX = A4_HEIGHT / page.GetPageSizeWithRotation().GetWidth();
        scaleY = A4_WIDTH / page.GetPageSizeWithRotation().GetHeight();
    }

    page.SetMediaBox(crop);
    page.SetCropBox(crop);

    if (scaleX != 1 || scaleY != 1)
    {
        double scale = Math.Min(scaleX, scaleY);
        string scaleString = scale.ToString("G17", CultureInfo.InvariantCulture);
        string s = $"\nq {scaleString} 0 0 {scaleString} 0 0 cm\nq\n";

        new PdfCanvas(page.NewContentStreamBefore(), new PdfResources(), pdf).WriteLiteral(s);
        new PdfCanvas(page.NewContentStreamAfter(), new PdfResources(), pdf).WriteLiteral("\nQ\nQ\n");

        IList<PdfAnnotation> annotations = page.GetAnnotations();
        ScaleAnnotations(scale, annotations);
    }
}
private static void ScaleAnnotations(double scale, IEnumerable<PdfAnnotation> annotations)
{
    foreach (var annotation in annotations)
    {
        Rectangle annotationRect = annotation.GetRectangle().ToRectangle();
        float newX = (float)(annotationRect.GetX() * scale);
        float newY = (float)(annotationRect.GetY() * scale);
        float newWidth = (float)(annotationRect.GetWidth() * scale);
        float newHeight = (float)(annotationRect.GetHeight() * scale);

        PdfArray newRectArray = new()
        {
            new PdfNumber(newX),
            new PdfNumber(newY),
            new PdfNumber(newX + newWidth),
            new PdfNumber(newY + newHeight)
        };

        annotation.SetRectangle(newRectArray);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.