2017-04-06 132 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