2017-04-06 72 views
1

我使用FDF中的表单字段导出PDF,并编写了一个子表达字段值的单元格值,以逐字输出另一个FDF。如果我在一个文本编辑器编辑FDF和更改值时,Acrobat可以读取文件就好了,但VBA文件输出抛出一个错误:Acrobat无法读取使用Excel VBA编写的.FDF

Adobe could not open whatever.fdf because it is either not a supported file type or because the file has been damaged

我已经尝试了两种不同类型的换行符,我已经尝试了与xfdf格式相似的子文件,它与相同的结果略有不同。

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 
+0

我怀疑编码问题。考虑使用'StrConv'函数来确保正确的编码('vbUnicode'?) –

+0

好的标注,但没有用vbunicode –

+0

'“%ÏÓ”'是ANSI编码的字符串 - 如果这意味着unicode,'vbUnicode'-编码'“%ÏÓ”''可能不会神奇地将它变成unicode等价物;您可能需要将它与'ChrW'结合使用来发布*实际* unicode字符。 –

回答

0

尽管我想离开这个开放,希望有人弄清楚为什么VBA搞砸了unicode,我的问题可以解决而无需调用fso,只需使用FreeFile和字符串替换或iginal 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 
+0

现在我真的很想知道你使用FDF来填补表格。使用Acrobat,您可以使用JSObject直接填写它。 – ReFran

+0

* facepalm *哇我没有意识到这一点。我会再次查看API手册,看看我必须做什么 –

1

只需离开了行: “%âãÏÓ” & 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 
+0

不幸的是同样的错误。我只是不明白。如果我在NP ++中并排查看文件,它们看起来完全相同。我可以编辑原始导出,它仍然可以工作。地狱,如果我复制并从原始粘贴到一个新的文件,它的作品。 VBA写的东西使得它无用。我想我可以尝试一个长的字符串替换循环的原始,但我没有真正做到这一点,所以它可能需要一些时间。 –

+0

德国有点晚了。如果你没有得到它,我明天会花费你一个vbs。 – ReFran

1

您会在Acrobat IAC文档中找到。这里有一个快速的vbs(vba)例子。你只需要2行: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