sourcecode

PDF에서 데이터 추출 후 워크시트에 추가

codebag 2023. 9. 15. 20:59
반응형

PDF에서 데이터 추출 후 워크시트에 추가

PDF 문서에서 워크시트로 데이터를 추출하려고 합니다.PDF 쇼와 텍스트는 수동으로 복사하여 엑셀 문서에 붙여넣을 수 있습니다.

저는 현재 SendKeys를 통해 이것을 하고 있는데 작동이 안 됩니다.PDF 문서의 데이터를 붙여넣으려고 하면 오류가 발생합니다.제 페이스트가 왜 안 되나요?매크로 실행이 중지된 후 붙여넣기하면 정상적으로 붙여넣기됩니다.

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

PDF 파일을 열고 Adobe 라이브러리를 사용하여 내용을 추출할 수 있습니다. (SDK의 일부로 Adobe에서 다운로드할 수 있지만 특정 버전의 Acrobat도 함께 제공됩니다.)

라이브러리도 참조에 추가하십시오(내 컴퓨터에서는 Adobe Acrobat 10.0 Type Library이지만 최신 버전인지 확실하지 않음).

Adobe 라이브러리를 사용하더라도 사소하지 않습니다(오류 트랩 등을 추가해야 함).

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

이 작업은 기본적으로 사용자가 시도하는 것과 동일한 작업이며 Adobe의 자체 라이브러리만 사용합니다.PDF를 한 번에 한 페이지씩 통과하여 페이지에 있는 모든 텍스트를 강조 표시한 다음 문자열에 해당 텍스트 요소(한 번에 하나씩)를 드롭합니다.

이를 통해 얻을 수 있는 것은 연속된 텍스트 블록처럼 보이는 인쇄되지 않은 모든 종류의 문자(줄 피드, 새 줄 등)로 가득 차 있을 수 있으므로 사용하기 전에 해당 문자를 정리하기 위해 추가 코드가 필요할 수 있습니다.

도움이 되기를 바랍니다!

이것이 오래된 문제라는 것을 알고 있지만, 저는 단지 직장에서 프로젝트를 위해 이 작업을 해야 했을 뿐인데, 아직 아무도 이 솔루션을 생각해내지 못했다는 것이 매우 놀랍습니다. 마이크로소프트 워드로 .pdf를 열면 됩니다.

코드는 Microsoft Word에서 열리므로 .docx에서 데이터를 추출할 때 훨씬 쉽게 작업할 수 있습니다.엑셀과 워드는 마이크로소프트 프로그램이기 때문에 잘 어울립니다.제 경우에는 문제의 파일이 .pdf 파일이어야 했습니다.제가 생각해낸 해결책은 다음과 같습니다.

  1. .pdf 파일을 열 기본 프로그램을 선택하여 Microsoft Word로 지정합니다.
  2. 단어가 포함된 .pdf 파일을 처음 열면 .pdf를 .docx 파일로 변환해야 한다는 대화 상자가 나타납니다.왼쪽 하단에 있는 "이 메시지를 다시 표시하지 않음"이라는 확인란을 누른 후 확인을 누릅니다.
  3. .docx 파일에서 데이터를 추출하는 매크로를 만듭니다.나는 이를 위한 자원으로 MikeD의 Code를 사용했습니다.
  4. 아래로 이동, 오른쪽으로 이동, 찾기로 만지작거립니다.작업의 필요에 맞게 메소드를 실행합니다.

네. 그냥 .pdf 파일을 .docx 파일로 변환할 수 있지만 제 생각에는 이것이 훨씬 더 간단한 해결책입니다.

시간이 흐르면서 PDF에서 구조화된 형식으로 텍스트를 추출하는 것은 어려운 일이라는 것을 알게 되었습니다.그러나 쉬운 해결책을 찾고 있다면 XPDF 도구를 고려해 볼 수 있습니다.pdftotext.

텍스트를 추출하기 위한 의사 코드는 다음과 같습니다.

  1. 을 해서.SHELLXPDF를 사용하여 PDF에서 임시 파일로 텍스트를 추출하는 VBA 문
  2. 순차적 파일 읽기 문을 사용하여 임시 파일 내용을 문자열로 읽기
  3. 문자열을 Excel에 붙여넣기

아래의 간략화된 예:

    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

저는 외부 라이브러리 및/또는 다른 프로그램에 의존하는 것을 선호하지 않기 때문에 솔루션이 작동하도록 확장했습니다.여기서 실질적인 변화는 다양한 셀을 붙여넣는 데 주로 사용되는 붙여넣기 대신 GetFromClipboard 기능을 사용하는 것입니다.물론 단점은 모든 과정에서 사용자가 초점을 바꾸거나 개입해서는 안 된다는 것입니다.

Dim pathPDF As String, textPDF As String
Dim openPDF As Object
Dim objPDF As MsForms.DataObject

pathPDF = "C:\some\path\data.pdf"
Set openPDF = CreateObject("Shell.Application")
openPDF.Open (pathPDF)
'TIME TO WAIT BEFORE/AFTER COPY AND PASTE SENDKEYS
Application.Wait Now + TimeValue("00:00:2")
SendKeys "^a"
Application.Wait Now + TimeValue("00:00:2")
SendKeys "^c"
Application.Wait Now + TimeValue("00:00:1")

AppActivate ActiveWorkbook.Windows(1).Caption
objPDF.GetFromClipboard
textPDF = objPDF.GetText(1)
MsgBox textPDF

관심 있으시면 github에서 제 프로젝트를 보세요.

사용자 상호 작용에 의한 복사 및 붙여넣기 에뮬레이션을 신뢰할 수 없습니다(예: 팝업이 나타나고 포커스가 전환됨).PDF에서 데이터를 추출할 수 있도록 특별히 설계되어 VBA에서 작동하는 상용 ByteScout PDF Extractor SDK를 사용해 보십시오.또한 VB 코드를 사용하여 송장 및 테이블에서 CSV로 데이터를 추출할 수 있습니다.

하여 Δ엑셀 ΔVBA 입니다.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

공개:저는 ByteScout와 관련이 있습니다.

Bytescout PDF Extractor SDK를 사용하는 것이 좋습니다.가격도 저렴하고 PDF 관련 기능도 풍부합니다.위의 답변 중 하나는 GitHub의 Bytescout 페이지를 가리키고 있습니다.PDF에서 표를 추출하기 위해 관련 작업 샘플을 제공합니다.어떤 형식으로든 내보낼 수 있습니다.

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

더 많은 샘플을 여기에서 이용할 수 있습니다: https://github.com/bytescout/pdf-extractor-sdk-samples

슬링키 나무늘보의 해결책을 개선하기 위해 클립보드에서 돌아오기 전에 이 내용을 추가해야 했습니다.

Set objPDF = New MSForms.DataObject

슬프게도 그것은 10페이지의 pdf 동안 작동하지 않았습니다.

Adobe Type 라이브러리에서는 작동하지 않는 것 같습니다.오픈이 되자마자 429 에러가 발생합니다.곡예사는 잘 하지만...

언급URL : https://stackoverflow.com/questions/36270247/extract-data-from-pdf-and-add-to-worksheet

반응형