Acrobat 无法读取用 Excel VBA 编写的 .FDF
Acrobat cannot read .FDF written with Excel VBA
我在 FDF 中导出了一个带有表单字段的 PDF,并编写了一个子程序来逐字输出另一个 FDF,其中包含表单字段值的单元格值。如果我在文本编辑器中编辑 FDF 并更改值,Acrobat 可以很好地读取文件,但带有 VBA 的文件输出会引发错误:
Adobe could not open whatever.fdf because it is either not a supported file type or because the file has been damaged
我试过两种不同类型的换行符,我试过一个类似的 xfdf 格式的 sub,它略有不同但结果相同。
Sub something()
Dim sht As Worksheet
Set sht = Sheets("owssvr")
Dim lastrow As Integer
lastrow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim Fileout As Object
Dim x As Integer
For x = 2 To lastrow
Set Fileout = fso.CreateTextFile("C:\Users\blabla\" & x & ".fdf", True, True)
Fileout.Write "%FDF-1.2" & vbCrLf & _
"%âãÏÓ" & vbCrLf & _
"1 0 obj" & vbCrLf & _
"<</FDF<</F(MyDocument.pdf)/Fields[<</T(Adobe Form Field)/V(" & sht.Range("U" & x) & ")>>]/ID[<4ED54800AC4A3D41ABE4F4C7B12A3D23><609E705B7532334B8F914CFF4C09F2A0>]/UF(MyDocument.pdf)>>/Type/Catalog>>" & vbCrLf & _
"endobj" & vbCrLf & _
"trailer" & vbCrLf & _
"<</Root 1 0 R>>" & vbCrLf & _
"%%EOF" & vbCrLf
Fileout.Close
Next x
End Sub
简单地省略行:“%âãÏÓ”& vbCrLf & _”。/ID 和 /UF 键并不是真正需要的。
像这样的东西应该可以工作:
Fileout.Write "%FDF-1.2" & vbCrLf & _
"1 0 obj<</FDF<<" & vbCrLf & _
"/F(MyDocument.pdf)" & vbCrLf & _
"/Fields" & vbCrLf & _
"[<</T(Adobe Form Field)/V(xyValue)>>]" & vbCrLf & _
">>>>" & vbCrLf & _
"endobj" & vbCrLf & _
"trailer" & vbCrLf & _
"<</Root 1 0 R>>" & vbCrLf & _
"%%EOF" & vbCrLf
虽然我很想打开它,希望有人能弄清楚为什么 VBA 搞砸了 unicode,但我的问题可以在根本不调用 fso 的情况下解决,只需使用 FreeFile 和字符串替换原始 FDF
Sub blabla()
Dim objAcroApp As Acrobat.AcroApp
Dim objAcroAVDoc As Acrobat.AcroAVDoc
Dim objAcroPDDoc As Acrobat.AcroPDDoc
Dim jsObj As Object
Dim boResult As Boolean
Dim oldPDF As String
Dim NewFilePath As String
Dim sTemp As String
Dim iFileNum As Integer
Dim oldFDF As String
Dim i As Integer
Dim lastRow As Integer
Dim sht As Worksheet
Set sht = Sheets("owssvr")
With sht
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
For i = 2 To lastRow
oldPDF = "\mydoc.pdf"
oldFDF = "\mydoc_data.fdf"
newPDF = "\" & i & ".pdf"
iFileNum = FreeFile
Open oldFDF For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTemp = sTemp & vbCrLf
Loop
Close iFileNum
sTemp = Replace(sTemp, "<</T(some form field)/V( )>>", "<</T(some form field)/V(" & sht.Range("E" & i) & ")>>")
iFileNum = FreeFile
oldFDF = "\" & i & ".fdf"
Open oldFDF For Output As iFileNum
Print #iFileNum, sTemp
Close iFileNum
Set objAcroApp = CreateObject("AcroExch.App")
Set objAcroAVDoc = CreateObject("AcroExch.AVDoc")
boResult = objAcroAVDoc.Open(oldPDF, "")
Set objAcroPDDoc = objAcroAVDoc.GetPDDoc
Set jsObj = objAcroPDDoc.GetJSObject
jsObj.ImportAnFDF oldFDF
jsObj.SaveAs newPDF
boResult = objAcroAVDoc.Close(True)
boResult = objAcroApp.Exit
Next i
End Sub
您会在 Acrobat IAC 文档中找到它。这是一个快速的 vbs(vba) 示例。你只需要其中的两行:jso.getField 和 f.value =...祝你好运。
'//-> Set a value for a form field via JSO
'//-> Settings
FileNm = "d:\TestInput.pdf"
FieldNm= "Input1"
FieldValue= "50"
'//-> let's start
Set App = CreateObject("Acroexch.app")
app.show
Set AVDoc = CreateObject("AcroExch.AVDoc")
'//-> open the file and put the value in
If AVDoc.Open(FileNM,"") Then
Set PDDoc = AVDoc.GetPDDoc()
Set jso = PDDoc.GetJSObject
'//-> Get the field and put a value in
set f = jso.getField(FieldNm)
f.value = FieldValue
end if
我在 FDF 中导出了一个带有表单字段的 PDF,并编写了一个子程序来逐字输出另一个 FDF,其中包含表单字段值的单元格值。如果我在文本编辑器中编辑 FDF 并更改值,Acrobat 可以很好地读取文件,但带有 VBA 的文件输出会引发错误:
Adobe could not open whatever.fdf because it is either not a supported file type or because the file has been damaged
我试过两种不同类型的换行符,我试过一个类似的 xfdf 格式的 sub,它略有不同但结果相同。
Sub something()
Dim sht As Worksheet
Set sht = Sheets("owssvr")
Dim lastrow As Integer
lastrow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim Fileout As Object
Dim x As Integer
For x = 2 To lastrow
Set Fileout = fso.CreateTextFile("C:\Users\blabla\" & x & ".fdf", True, True)
Fileout.Write "%FDF-1.2" & vbCrLf & _
"%âãÏÓ" & vbCrLf & _
"1 0 obj" & vbCrLf & _
"<</FDF<</F(MyDocument.pdf)/Fields[<</T(Adobe Form Field)/V(" & sht.Range("U" & x) & ")>>]/ID[<4ED54800AC4A3D41ABE4F4C7B12A3D23><609E705B7532334B8F914CFF4C09F2A0>]/UF(MyDocument.pdf)>>/Type/Catalog>>" & vbCrLf & _
"endobj" & vbCrLf & _
"trailer" & vbCrLf & _
"<</Root 1 0 R>>" & vbCrLf & _
"%%EOF" & vbCrLf
Fileout.Close
Next x
End Sub
简单地省略行:“%âãÏÓ”& vbCrLf & _”。/ID 和 /UF 键并不是真正需要的。
像这样的东西应该可以工作:
Fileout.Write "%FDF-1.2" & vbCrLf & _
"1 0 obj<</FDF<<" & vbCrLf & _
"/F(MyDocument.pdf)" & vbCrLf & _
"/Fields" & vbCrLf & _
"[<</T(Adobe Form Field)/V(xyValue)>>]" & vbCrLf & _
">>>>" & vbCrLf & _
"endobj" & vbCrLf & _
"trailer" & vbCrLf & _
"<</Root 1 0 R>>" & vbCrLf & _
"%%EOF" & vbCrLf
虽然我很想打开它,希望有人能弄清楚为什么 VBA 搞砸了 unicode,但我的问题可以在根本不调用 fso 的情况下解决,只需使用 FreeFile 和字符串替换原始 FDF
Sub blabla()
Dim objAcroApp As Acrobat.AcroApp
Dim objAcroAVDoc As Acrobat.AcroAVDoc
Dim objAcroPDDoc As Acrobat.AcroPDDoc
Dim jsObj As Object
Dim boResult As Boolean
Dim oldPDF As String
Dim NewFilePath As String
Dim sTemp As String
Dim iFileNum As Integer
Dim oldFDF As String
Dim i As Integer
Dim lastRow As Integer
Dim sht As Worksheet
Set sht = Sheets("owssvr")
With sht
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
For i = 2 To lastRow
oldPDF = "\mydoc.pdf"
oldFDF = "\mydoc_data.fdf"
newPDF = "\" & i & ".pdf"
iFileNum = FreeFile
Open oldFDF For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTemp = sTemp & vbCrLf
Loop
Close iFileNum
sTemp = Replace(sTemp, "<</T(some form field)/V( )>>", "<</T(some form field)/V(" & sht.Range("E" & i) & ")>>")
iFileNum = FreeFile
oldFDF = "\" & i & ".fdf"
Open oldFDF For Output As iFileNum
Print #iFileNum, sTemp
Close iFileNum
Set objAcroApp = CreateObject("AcroExch.App")
Set objAcroAVDoc = CreateObject("AcroExch.AVDoc")
boResult = objAcroAVDoc.Open(oldPDF, "")
Set objAcroPDDoc = objAcroAVDoc.GetPDDoc
Set jsObj = objAcroPDDoc.GetJSObject
jsObj.ImportAnFDF oldFDF
jsObj.SaveAs newPDF
boResult = objAcroAVDoc.Close(True)
boResult = objAcroApp.Exit
Next i
End Sub
您会在 Acrobat IAC 文档中找到它。这是一个快速的 vbs(vba) 示例。你只需要其中的两行:jso.getField 和 f.value =...祝你好运。
'//-> Set a value for a form field via JSO
'//-> Settings
FileNm = "d:\TestInput.pdf"
FieldNm= "Input1"
FieldValue= "50"
'//-> let's start
Set App = CreateObject("Acroexch.app")
app.show
Set AVDoc = CreateObject("AcroExch.AVDoc")
'//-> open the file and put the value in
If AVDoc.Open(FileNM,"") Then
Set PDDoc = AVDoc.GetPDDoc()
Set jso = PDDoc.GetJSObject
'//-> Get the field and put a value in
set f = jso.getField(FieldNm)
f.value = FieldValue
end if