Excel 从PDF中提取数据并添加到工作表
我试图将PDF文档中的数据提取到工作表中。PDF显示和文本可以手动复制并粘贴到Excel文档中 我目前正在通过SendKeys执行此操作,但它不起作用。尝试粘贴PDF文档中的数据时出错。为什么我的粘贴不起作用?如果在宏停止运行后粘贴,它将按正常方式粘贴Excel 从PDF中提取数据并添加到工作表,excel,vba,pdf,Excel,Vba,Pdf,我试图将PDF文档中的数据提取到工作表中。PDF显示和文本可以手动复制并粘贴到Excel文档中 我目前正在通过SendKeys执行此操作,但它不起作用。尝试粘贴PDF文档中的数据时出错。为什么我的粘贴不起作用?如果在宏停止运行后粘贴,它将按正常方式粘贴 Dim myPath As String, myExt As String Dim ws As Worksheet Dim openPDF As Object 'Dim pasteData As MSForms.DataObject Dim fC
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
Dim myPath作为字符串,myExt作为字符串
将ws设置为工作表
Dim openPDF作为对象
'将数据作为MSForms.DataObject粘贴
变暗fCell As范围
'设置粘贴数据=新的MSForms.DataObject
设置ws=图纸(“数据”)
如果ws.Cells(ws.Rows.Count,“A”).End(xlUp).Row>1,则范围(“A3:A”和ws.Cells(ws.Rows.Count,“A”).End(xlUp).Row.ClearContent
myExt=“\*.pdf”
'当按下扫描收据按钮时,扫描所选文件夹中的收据
对于范围内的每个fCell(ws.Cells(1,1),ws.Cells(1,ws.Cells(1,ws.Columns.Count).End(xlToLeft.Column))
myPath=Dir(fCell.Value&myExt)
在myPath“”时执行此操作
myPath=fCell.Value&“\”&myPath
设置openPDF=CreateObject(“Shell.Application”)
openPDF.Open(myPath)
应用程序。立即等待+时间值(“00:00:2”)
发送密钥“^a”
应用程序。立即等待+时间值(“00:00:2”)
发送密钥“^c”
'Application.Wait Now+时间值(“00:00:2”)
ws.Select
活动表。粘贴
'pasteData.GetFromClipboard
'ws.Cells(3,1)=pasteData.GetText
出口接头
myPath=Dir
环
下一个fCell
您可以使用Adobe library打开PDF文件并提取其内容(我相信您可以将其作为SDK的一部分从Adobe下载,但它还附带某些版本的Acrobat)
确保也将库添加到引用中(在我的机器上,它是Adobe Acrobat 10.0类型库,但不确定它是否是最新版本)
即使使用Adobe library,它也不是微不足道的(您需要添加自己的错误捕获等):
这与您尝试做的基本相同——只使用Adobe自己的库。它一次浏览一个PDF页面,突出显示页面上的所有文本,然后将其(一次一个文本元素)放入字符串中
记住,从中获取的所有类型的非打印字符(行提要、换行符等)甚至可能在类似连续文本块的中间结束,因此您可能需要额外的代码在使用之前清理它。
希望有帮助 随着时间的推移,我发现以结构化格式从PDF中提取文本是一件困难的事情。但是,如果您正在寻找一个简单的解决方案,您可能需要考虑工具<代码> PDFTOTEX< /COD> 提取文本的伪代码包括:
SHELL
VBA语句使用 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
通过用户交互模拟进行复制和粘贴可能不可靠(例如,出现弹出窗口并切换焦点)。您可能有兴趣尝试专门设计用于从PDF中提取数据的广告,它可以从VBA中工作。它还能够使用CSV从发票和表格中提取数据 下面是用于Excel的VBA代码,用于从给定位置提取文本并将其保存到
工作表1的单元格中:
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有关,使用是一个很好的选择。它价格便宜,提供了大量与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
这里提供了更多示例:由于我不喜欢依赖外部库和/或其他程序,因此我扩展了您的解决方案,使其能够正常工作。
这里的实际更改是使用GetFromClipboard函数,而不是主要用于粘贴一系列单元格的Paste函数。
当然,缺点是用户不能在整个过程中改变焦点或干预
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
如果您有兴趣在中查看我的项目。为了改进Slinky Sloth的解决方案,我必须在从剪贴板获取之前添加以下内容:
Set objPDF = New MSForms.DataObject
遗憾的是,它不适用于10页的pdf。这似乎不适用于Adobe类型库。它一打开,我就得到一个429错误。Acrobat工作得很好,但…我知道这是一个老问题,但我只是为了工作中的一个项目才这样做,我很惊讶还没有人想到这个解决方案:
只要用Microsoft word打开.pdf即可。
当您试图从.docx中提取数据时,使用该代码要容易得多,因为它是在Microsoft Word中打开的。Excel和Word都是Microsoft程序,因此两者配合得很好。在我的例子中,问题文件必须是.pdf文件。以下是我提出的解决方案:
选择默认程序以打开Microsoft Word中的.pdf文件
第一次使用word打开.pdf文件时,会弹出一个对话框,声称word需要将.pdf文件转换为.docx文件。单击左下角的“不再显示此邮件”复选框,然后单击“确定”
创建从.docx文件中提取数据的宏。我用它作为一个资源
修改MoveDown、MoveRight和Find.Execute方法以满足任务的需要
是的,您可以将.pdf文件转换为.docx文件,但在我看来,这是一个简单得多的解决方案。Adobe Library绝对是一个不错的选择。需要注意的是,它可以比您显示的功能更强大,因为它可以从单个文本框块或其他对象中获取文本,这可能更简洁
Set objPDF = New MSForms.DataObject