Vb.net 使用PDFSharp将PDF转换为文本

Vb.net 使用PDFSharp将PDF转换为文本,vb.net,pdf,pdfsharp,Vb.net,Pdf,Pdfsharp,我编写了以下函数来读取PDF文件中的文本。这是非常接近,但我只是不够熟悉所有的操作代码,以获得正确的行距。例如,当我看到“ET”时,我正在插入一个新行,但这似乎不太正确,因为它可能只是文本运行的结束,中间行。有人能帮我调整一下语法吗?我的目标类似于Adobe Reader的“另存为其他”-->“文本” 您的代码忽略了几乎所有更改行的操作。你应该考虑 和 ,这通常意味着线的变化,但在野外很少使用。 因此,在文本对象(BT。ET)中,您还应该注意 tx tyTd移动到下一行的起点,与当前行的起点偏

我编写了以下函数来读取PDF文件中的文本。这是非常接近,但我只是不够熟悉所有的操作代码,以获得正确的行距。例如,当我看到“ET”时,我正在插入一个新行,但这似乎不太正确,因为它可能只是文本运行的结束,中间行。有人能帮我调整一下语法吗?我的目标类似于Adobe Reader的“另存为其他”-->“文本”


您的代码忽略了几乎所有更改行的操作。你应该考虑<强> <强>和<强> <强>,这通常意味着线的变化,但在野外很少使用。

因此,在文本对象(BTET)中,您还应该注意

  • tx tyTd移动到下一行的起点,与当前行的起点偏移(tx,ty)
  • tx tyTD移动到下一行的开头,与当前行的开头偏移(tx,ty)。作为副作用,该操作员应在文本状态下设置前导参数
  • a b c d e fTm设置文本矩阵Tm和文本行矩阵Tlm
  • T*移动到下一行的开头
要正确解释T*,还应注意

  • 行距TL将文本行距TL设置为行距
如果找到多个文本对象(BTETBTET),则第二个文本对象不一定位于新行。您应该注意它们之间的特殊图形状态运算符:

  • a b c d e fcm通过串联修改当前变换矩阵(CTM) 指定矩阵
  • q保存当前图形状态
  • Q恢复图形状态

您的代码正在忽略操作的所有数值参数。你不应该忽视它们,尤其是:

  • 您应该检查上面列出的运算符的参数;e、 g.当
    0-20 Td
    向下20个单位开始一个新行时,
    20 0 Td
    保持在同一行上,仅在前一行开始的20个单位右侧开始绘制文本
  • 您应该检查TJ数组参数的数字元素,因为它们可能(也可能不!)表示两个单词之间的空格
您的代码假定
CString
实例的
已包含Unicode编码的字符数据。这种假设通常是不正确的,在文本绘制操作中绘制的PDF字符串中使用的编码由字体决定。因此,你还应该注意

  • font sizeTf将文本字体Tf设置为font,将文本字体大小Tfs设置为size。字体应为当前资源字典的font子字典中字体资源的名称

有关详细信息,您应该首先学习PDF规范,尤其是第8章图形中具有坚实背景的第9章文本。

您的代码忽略了几乎所有更改行的操作。你应该考虑<强> <强>和<强> <强>,这通常意味着线的变化,但在野外很少使用。

因此,在文本对象(BTET)中,您还应该注意

  • tx tyTd移动到下一行的起点,与当前行的起点偏移(tx,ty)
  • tx tyTD移动到下一行的开头,与当前行的开头偏移(tx,ty)。作为副作用,该操作员应在文本状态下设置前导参数
  • a b c d e fTm设置文本矩阵Tm和文本行矩阵Tlm
  • T*移动到下一行的开头
要正确解释T*,还应注意

  • 行距TL将文本行距TL设置为行距
如果找到多个文本对象(BTETBTET),则第二个文本对象不一定位于新行。您应该注意它们之间的特殊图形状态运算符:

  • a b c d e fcm通过串联修改当前变换矩阵(CTM) 指定矩阵
  • q保存当前图形状态
  • Q恢复图形状态

您的代码正在忽略操作的所有数值参数。你不应该忽视它们,尤其是:

  • 您应该检查上面列出的运算符的参数;e、 g.当
    0-20 Td
    向下20个单位开始一个新行时,
    20 0 Td
    保持在同一行上,仅在前一行开始的20个单位右侧开始绘制文本
  • 您应该检查TJ数组参数的数字元素,因为它们可能(也可能不!)表示两个单词之间的空格
您的代码假定
CString
实例的
已包含Unicode编码的字符数据。这种假设通常是不正确的,在文本绘制操作中绘制的PDF字符串中使用的编码由字体决定。因此,你还应该注意

  • font sizeTf将文本字体Tf设置为font,将文本字体大小Tfs设置为size。字体应为当前资源字典的font子字典中字体资源的名称
有关详细信息,请首先
Public Function ReadPDFFile(filePath As String,
                            Optional maxLength As Integer = 0) As String

    Dim sbContents As New StringBuilder

    Dim cArrayType As Type = GetType(CArray)
    Dim cCommentType As Type = GetType(CComment)
    Dim cIntegerType As Type = GetType(CInteger)
    Dim cNameType As Type = GetType(CName)
    Dim cNumberType As Type = GetType(CNumber)
    Dim cOperatorType As Type = GetType(COperator)
    Dim cRealType As Type = GetType(CReal)
    Dim cSequenceType As Type = GetType(CSequence)
    Dim cStringType As Type = GetType(CString)
    Dim opCodeNameType As Type = GetType(OpCodeName)

    Dim ReadObject As Action(Of CObject) = Sub(obj As CObject)

                                               Dim objType As Type = obj.GetType

                                               Select Case objType
                                                   Case cArrayType
                                                       Dim arrObj As CArray = DirectCast(obj, CArray)
                                                       For Each member As CObject In arrObj
                                                           ReadObject(member)
                                                       Next
                                                   Case cOperatorType
                                                       Dim opObj As COperator = DirectCast(obj, COperator)
                                                       Select Case System.Enum.GetName(opCodeNameType, opObj.OpCode.OpCodeName)
                                                           Case "ET", "Tx"
                                                               sbContents.Append(vbNewLine)
                                                           Case "Tj", "TJ"
                                                               For Each operand As CObject In opObj.Operands
                                                                   ReadObject(operand)
                                                               Next
                                                           Case "QuoteSingle", "QuoteDbl"
                                                               sbContents.Append(vbNewLine)
                                                               For Each operand As CObject In opObj.Operands
                                                                   ReadObject(operand)
                                                               Next
                                                           Case Else
                                                               'Do Nothing
                                                       End Select
                                                   Case cSequenceType
                                                       Dim seqObj As CSequence = DirectCast(obj, CSequence)
                                                       For Each member As CObject In seqObj
                                                           ReadObject(member)
                                                       Next
                                                   Case cStringType
                                                       sbContents.Append(DirectCast(obj, CString).Value)
                                                   Case cCommentType, cIntegerType, cNameType, cNumberType, cRealType
                                                       'Do Nothing
                                                   Case Else
                                                       Throw New NotImplementedException(obj.GetType().AssemblyQualifiedName)
                                               End Select

                                           End Sub

    Using pd As PdfDocument = PdfReader.Open(filePath, PdfDocumentOpenMode.ReadOnly)

        For Each page As PdfPage In pd.Pages

            ReadObject(ContentReader.ReadContent(page))

            If maxLength > 0 And sbContents.Length >= maxLength Then
                If sbContents.Length > maxLength Then
                    sbContents.Remove(maxLength - 1, sbContents.Length - maxLength)
                End If
                Exit For
            End If

            sbContents.Append(vbNewLine)

        Next

    End Using

    Return sbContents.ToString

End Function