VBA-extrair dados do PDF e Adicionar à folha de trabalho

Tenho um projecto onde estou a tentar extrair os dados de um documento PDF para uma folha de trabalho. O PDF já é mostrado e texto e pode ser copiado e colado manualmente no documento Excel.

Estou neste momento a fazer este projecto através do SendKeys e ele não está a funcionar muito bem, pois recebo um erro quando tento colar os dados do documento PDF seja qual for o método que use! Alguém conhece uma maneira mais bonita de fazer as coisas? Seria uma grande ajuda! E também, porque é que a minha pasta não a trabalhar?! Se eu colar depois que a macro parou de correr passa como normal? Código Abaixo:

Dim myPath As String, myExt As String
Dim ws As Worksheet
Dim openPDF As Object
'Dim pasteData As MSForms.DataObject
Dim fCell As Range

'Set pasteData = New MSForms.DataObject
Set ws = Sheets("DATA")
If ws.Cells(ws.Rows.Count, "A").End(xlUp).Row > 1 Then Range("A3:A" & ws.Cells(ws.Rows.Count, "A").End(xlUp).Row).ClearContents

myExt = "\*.pdf"
'When Scan Receipts Button Pressed Scan the selected folder/s for receipts
For Each fCell In Range(ws.Cells(1, 1), ws.Cells(1, ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column))
    myPath = Dir(fCell.Value & myExt)
    Do While myPath <> ""
        myPath = fCell.Value & "\" & myPath
        Set openPDF = CreateObject("Shell.Application")
        openPDF.Open (myPath)
        Application.Wait Now + TimeValue("00:00:2")
        SendKeys "^a"
        Application.Wait Now + TimeValue("00:00:2")
        SendKeys "^c"
        'Application.Wait Now + TimeValue("00:00:2")
        ws.Select
        ActiveSheet.Paste
        'pasteData.GetFromClipboard

        'ws.Cells(3, 1) = pasteData.GetText
        Exit Sub

        myPath = Dir
    Loop

Next fCell
Author: Will Bell, 2016-03-28

4 answers

Você pode abrir o arquivo PDF e extrair seu conteúdo usando a Biblioteca Adobe (que eu acredito que você pode baixar do Adobe como parte do SDK, mas ele vem com certas versões do Acrobat também)

Certifique-se de adicionar a Biblioteca às suas referências também (na minha máquina é a Biblioteca do tipo Adobe Acrobat 10.0, mas não tenho a certeza se essa é a versão mais recente)

Mesmo com a biblioteca Adobe não é trivial (você vai precisar adicionar sua própria armadilha de erros etc):

Function getTextFromPDF(ByVal strFilename As String) As String
   Dim objAVDoc As New AcroAVDoc
   Dim objPDDoc As New AcroPDDoc
   Dim objPage As AcroPDPage
   Dim objSelection As AcroPDTextSelect
   Dim objHighlight As AcroHiliteList
   Dim pageNum As Long
   Dim strText As String

   strText = ""
   If (objAvDoc.Open(strFilename, "") Then
      Set objPDDoc = objAVDoc.GetPDDoc
      For pageNum = 0 To objPDDoc.GetNumPages() - 1
         Set objPage = objPDDoc.AcquirePage(pageNum)
         Set objHighlight = New AcroHiliteList
         objHighlight.Add 0, 10000 ' Adjust this up if it's not getting all the text on the page
         Set objSelection = objPage.CreatePageHilite(objHighlight)

         If Not objSelection Is Nothing Then
            For tCount = 0 To objSelection.GetNumText - 1
               strText = strText & objSelection.GetText(tCount)
            Next tCount
         End If
      Next pageNum
      objAVDoc.Close 1
   End If

   getTextFromPDF = strText

End Function
O que isso faz é essencialmente a mesma coisa que você está tentando fazer - apenas usando a própria biblioteca do Adobe. Ele está indo através do PDF uma página de cada vez, destacando todo o texto na página, em seguida, largando-o (um elemento de texto de cada vez) em uma string.

Tenha em mente o que você obtém a partir disto pode estar cheio de todos os tipos de caracteres não-Impressão (feeds de linha, newlines, etc) que podem até acabar no meio do que se parecem com blocos contíguos de texto, para que você possa é preciso um código adicional para limpar antes de poder usá-lo.

Espero que isso ajude!
 7
Author: leowyn, 2016-03-28 20:44:08

Copiar e colar por interações do utilizador a emulação não pode ser fiável (por exemplo, aparece o popup e muda o foco). Você pode estar interessado em tentar o comercial ByteScout PDF Extractor SDK que é projetado especificamente para extrair dados de PDF e funciona a partir de VBA. É igualmente capaz de extrair dados de facturas e quadros como CSV utilizando o código VB.

Aqui está o código VBA para o Excel extrair texto de determinados locais e guardá - los em células na Sheet1:

Private Sub CommandButton1_Click()

' Create TextExtractor object
' Set extractor = CreateObject("Bytescout.PDFExtractor.TextExtractor")
Dim extractor As New Bytescout_PDFExtractor.TextExtractor

extractor.RegistrationName = "demo"
extractor.RegistrationKey = "demo"

' Load sample PDF document
extractor.LoadDocumentFromFile ("c:\sample1.pdf")

' Get page count
pageCount = extractor.GetPageCount()

Dim wb As Workbook
Dim ws As Worksheet
Dim TxtRng  As Range

Set wb = ActiveWorkbook
Set ws = wb.Sheets("Sheet1")

For i = 0 To pageCount - 1
            RectLeft = 10
            RectTop = 10
            RectWidth = 100
            RectHeight = 100

            ' check the same text is extracted from returned coordinates
            extractor.SetExtractionArea RectLeft, RectTop, RectWidth, RectHeight
            ' extract text from given area
            extractedText = extractor.GetTextFromPage(i)

            ' insert rows
            ' Rows(1).Insert shift:=xlShiftDown
            ' write cell value
             Set TxtRng = ws.Range("A" & CStr(i + 2))
             TxtRng.Value = extractedText

Next

Set extractor = Nothing


End Sub

divulgação: sou parente da ByteScout

 1
Author: Eugene M, 2016-03-30 15:44:43

Com o tempo, descobri que extrair texto de PDFs num formato estruturado é uma tarefa difícil. No entanto, se está à procura de uma solução fácil, pode querer considerar xpdf a ferramenta pdftotext.

Pseudocódigo para extrair o texto incluiria:

  1. usando SHELL a declaração VBA para extrair o texto do PDF para um ficheiro temporário usando XPDF
  2. usando declarações sequenciais de leitura de ficheiros para ler o conteúdo temporário do ficheiro num string
  3. Colando a string no Excel

Exemplo simplificado abaixo:

    Sub ReadIntoExcel(PDFName As String)
        'Convert PDF to text
        Shell "C:\Utils\pdftotext.exe -layout " & PDFName & " tempfile.txt"

        'Read in the text file and write to Excel
        Dim TextLine as String
        Dim RowNumber as Integer
        Dim F1 as Integer
        RowNumber = 1
        F1 = Freefile()
        Open "tempfile.txt" for Input as #F1
            While Not EOF(#F1)
                Line Input #F1, TextLine
                ThisWorkbook.WorkSheets(1).Cells(RowNumber, 1).Value = TextLine
                RowNumber = RowNumber + 1
            Wend
        Close #F1
    End Sub
 0
Author: RIBH, 2016-03-28 21:26:37

Usar Bytescout PDF Extractor SDK é uma boa opção. É barato e dá muita funcionalidade relacionada com PDF. Uma das respostas acima aponta para a página morta Bytescout em GitHub. Estou fornecendo uma amostra de trabalho relevante para extrair mesa de PDF. Você pode usá-lo para exportar em qualquer formato.

Set extractor = CreateObject("Bytescout.PDFExtractor.StructuredExtractor")

extractor.RegistrationName = "demo"
extractor.RegistrationKey = "demo"

' Load sample PDF document
extractor.LoadDocumentFromFile "../../sample3.pdf"

For ipage = 0 To extractor.GetPageCount() - 1 

    ' starting extraction from page #"
    extractor.PrepareStructure ipage

    rowCount = extractor.GetRowCount(ipage)

    For row = 0 To rowCount - 1 
        columnCount = extractor.GetColumnCount(ipage, row)

        For col = 0 To columnCount-1
            WScript.Echo "Cell at page #" +CStr(ipage) + ", row=" & CStr(row) & ", column=" & _
                CStr(col) & vbCRLF & extractor.GetCellValue(ipage, row, col)
        Next
    Next
Next

Muitas mais amostras disponíveis aqui: https://github.com/bytescout/pdf-extractor-sdk-samples

 0
Author: AbhishekTripathi, 2018-03-17 20:39:30