0

我已经为此苦苦挣扎了一段时间,所以我想我会将这个发布给任何能够找到解决方案的大师。

我有一个要复制的 PDF 文档,当我复制它时,我想将页面大小调整为自定义大小。例如,原始文档的页面大小为 8 1/2 x 16。新文档需要为 8 1/2 x 22。新文档中的 8 1/2 来自原文档的宽度;22 是固定的(常数)。使问题复杂化的是新文档需要将旧文档内容放在页面中心。因此,在新文档中,它需要具有顶部 3 英寸、底部 3 英寸的边距,以便原始的 16 英寸居中。宽度无关紧要,只是高度需要居中。

寻找 iTextSharp 的代码片段。

创建了以下有效的解决方案。发回社区,希望它可以帮助某人。解决方案在 VB.NET 中。

使用带有 2 个布尔值的调用 resizeAndRotateDocument。“旋转” - 将每一页旋转 90 度 - 真,假。和“调整大小” - 将页面大小调整为 22 英寸高度,并将页边距添加到顶部/底部到中心页面 - 真/假。还有 2 个字符串:要处理的输入 pdf 文件的名称和要创建的输出 pdf 文件的名称。

    Private Sub AdjustMediaBoxSize(ByRef mediaBoxSize As PdfArray, ByVal rotationIsPresent As Boolean)

    Const Fixed_22_Inch_Page As Integer = 22 * 72

    Dim ll_x, ll_y, ur_x, ur_y As Integer
    Dim heightDiff, heightAdjustment As Integer
    Dim new_ll_x, new_ll_y, new_ur_x, new_ur_y As Integer

    ' Read current coordinates of the Mediabox
    ll_x = mediaBoxSize(0).ToString
    ll_y = mediaBoxSize(1).ToString

    ur_x = mediaBoxSize(2).ToString
    ur_y = mediaBoxSize(3).ToString

    ' Figure out the height difference and the adjustment factor.
    If rotationIsPresent = True Then
        heightDiff = Fixed_22_Inch_Page - ur_x
    Else
        heightDiff = Fixed_22_Inch_Page - ur_y
    End If

    ' adjustment needed to top and to bottom
    heightAdjustment = heightDiff / 2

    ' Apply the adjustments; only use the ones we need.
    new_ll_x = ll_x - heightAdjustment
    new_ur_x = ur_x + heightAdjustment

    new_ll_y = ll_y - heightAdjustment
    new_ur_y = ur_y + heightAdjustment

    If rotationIsPresent = True Then
        mediaBoxSize(0) = New iTextSharp.text.pdf.PdfNumber(new_ll_x)
        mediaBoxSize(2) = New iTextSharp.text.pdf.PdfNumber(new_ur_x)
    Else
        ' Make the adjustment. Value is passed back by reference.
        mediaBoxSize(1) = New iTextSharp.text.pdf.PdfNumber(new_ll_y)
        mediaBoxSize(3) = New iTextSharp.text.pdf.PdfNumber(new_ur_y)
    End If

End Sub

Private Sub resizeAndRotateDocument(ByVal rotate As Boolean, ByVal resize As Boolean, ByVal inPDF As String, ByVal outPDF As String)

    Const desiredRot As Integer = 90

    Dim reader As New PdfReader(inPDF)
    Dim pageCount As Integer = reader.NumberOfPages

    Dim pageDict As PdfDictionary
    Dim mediabox As New PdfArray
    Dim cropbox As New PdfArray

    For i As Integer = 1 To pageCount

        pageDict = reader.GetPageN(i)

        ' Rotation is hard coded to 90 degrees.
        If rotate = True Then
            pageDict.Put(PdfName.ROTATE, New PdfNumber(desiredRot))
        End If

        If resize = True Then
            ' Read the current mediabox dimensions. 
            ' Then adjust the size to scale up to 22 inches adjusting for rotation if necessary.
            ' Finally, write the updated mediabox back to the dictionary -> to the reader.

            mediabox = pageDict.GetAsArray(PdfName.MEDIABOX)
            AdjustMediaBoxSize(mediabox, rotate)
            pageDict.Put(PdfName.MEDIABOX, mediabox)

        End If

        ' Since the PDFs are created in-house, they should NEVER contain a cropbox.
        cropbox = pageDict.GetAsArray(PdfName.CROPBOX)
        If cropbox IsNot Nothing Then
            MsgBox("Error ... found a valid cropbox !!!")
        End If

    Next

    ' Use the stamper to create and write the pdf output file.
    Dim pdfStamper As New PdfStamper(reader, New FileStream(outPDF, FileMode.Create))
    pdfStamper.Close()

End Sub

再次感谢布鲁诺!

4

1 回答 1

2

看看我书中的RotatePages示例。在该ManipulatePdf()方法中,我遍历页面,获取页面字典,并更改/Rotate键以旋转页面。这不是你需要的,但原理是相似的。

您需要从页面字典中获取/MediaBoxand值:/CropBox

PdfArray mediabox = pageDict.getAsArray(PdfName.MEDIABOX);
PdfArray cropbox = pageDict.getAsArray(PdfName.CROPBOX);

在许多情况下,cropbox 将null在这种情况下您可以放心地忽略它。

您的页面尺寸为 8 1/2 x 16 英寸,所以我猜 mediabox 将是一个如下所示的数组:[ 0 0 612 1152 ]

零点是左下角的坐标。右上角的坐标为 x = 612 (72 x 8.5) 和 y = 1152 (72 x 16)。

现在您需要用类似的数组替换 /MediaBox 条目,在该数组中从第二个值中减去 216 (72 x 3) 并将 216 添加到第四个值。换句话说:您最终会得到以下数组[ 0 -216 612 1368 ]。用这样一个改变的数组替换/MediaBox(和/CropBox如果存在的话),就像我替换/Rotate密钥一样,你就有了你的示例代码。

如果我是你,我不会使用绝对值,我会从你在页面字典中找到的数组中的任何值中减去 216。

免责声明:我是 iText 的原作者,以及从中获取旋转示例的“iText in Action”书籍的原作者。我是一名 Java 开发人员;我花钱请其他开发人员将我书中的示例移植到 C#。请不要让我用 C# 写出你的例子,因为我从来没有写过任何 C# 代码,只有 Java 代码。我相信您将能够使用本文中提供的信息编写满足您需求的代码。

于 2013-05-15T21:09:22.327 回答