2010-04-09 79 views
6

比方說,我在網站上有一個由用戶填寫並提交給服務器的pdf格式文件。在服務器端(Asp.Net),我想將我以xml格式接收到的數據與填充的空白pdf表單合併並保存。用xml數據合併/填充pdf格式文件

正如我發現有這樣做的幾種可能的方式:

  1. 使用的Adobe Acrobat創建PDF表單,並與iTextSharp的填充它。
  2. 使用adobe acrobat創建的pdf格式並填充FDF Toolkit .net(似乎在內部使用itextsharp)
  3. usd pdfkt填寫表單。
  4. 使用PDF格式文件與Adobe的LiveCycle創建,當我有這樣的任務,你可以建議哪一種方案會更好/更容易,給一些額外的提示,沒有經驗使用Form Data Integration Service

合併數據?

預先感謝您。

回答

0

既然你標記了這個'LiveCycle',我認爲你有安裝在任何地方運行的Adobe LiveCycle(可選地,可以將安裝在某處)。

在這種情況下,我會去4號(修改使用Adob​​e LiveCycle Forms ES模塊)。其他三個無疑將長期產生兼容性問題。使用LiveCycle服務器(運行Forms模塊),無論是舊的,新的,靜態的,動態的,壓縮的,基於Acrobat的還是基於LiveCycle的,您都可以處理任何 PDF。

您應該能夠設置,將表單發送到LiveCycle服務器,並使用該數據填充表單。然後可以將填充存儲在服務器的數據庫中,或者路由到PDF表單(或任何其他表單)並流式傳輸回客戶端。

使用LiveCycle Designer創建表單。

quick-and-dirty-option將如下所示:將表單設置爲http-post(例如xfdf,請參閱Acrobat以獲取更多信息)到您的ASP服務器併發布到服務器上確保你的用戶在打開它之前不要下載表單,否則這將不起作用,表單必須在網頁瀏覽器中打開)。然後簡單地捕獲提交內容,就像從網頁上捕獲http文章一樣。或者,將填充保存到數據庫。然後將捕獲的xfdf流填充回客戶端(也可以通過http-link在稍後階段調用)。 xfdf流將包含用於填充表單的URL。客戶端Web瀏覽器將要求Acrobat/Adob​​e閱讀器插件處理xfdf流,插件將定位,下載並填充xfdf指向的表單。

用戶現在應該可以保存表格並填寫 - 不需要Reader Extension!

+0

@Christian - 我需要保存的PDF文件的服務器上,而不是在用戶側。 – Giorgi 2010-04-20 07:17:50

3

如果可能的話,我會建議使用第4種方法,因爲它會更乾淨。您將使用專門針對您要求的解決方案進行量身定製的解決方案,但如果您沒有可用的解決方案資源,我建議您使用第一個選項。

第一個選項是我最近所做的。我發現實施起來相對無痛。

選項1是可能的,如果出現以下情況:

  1. 你的PDF形式的發展的控制。
  2. 你必須格式化XML數據的控制
  3. 你可以與具有無壓縮(FASTWEB = FALSE)PDF文件實施

例活:

  1. 使用Adobe Acrobat來生成PDF格式。提示:在生成表單時使用Adobe Native Fonts。對於添加的不是本地字體的每個控件,它將導入使用的字體並在文件未壓縮時膨脹該文件,就我所知,ITextSharp目前不生成壓縮的PDF。

  2. 使用ITextSharp庫將XML數據與PDF表單合併以生成填充文檔。提示:要從xml手動填充PDF表單,必須將xml值映射到PDF表單中的控件名稱,並按頁面進行匹配,如下例所示。

    using (MemoryStream stream = GeneratePDF(m_FormsPath, oXmlData)) 
    { 
         byte[] bytes = stream.ToArray(); 
         Response.ContentType = "application/pdf"; 
         Response.BinaryWrite(bytes); 
         Response.End(); 
    } 
    
    // <summary> 
    // This method combines pdf forms with xml data 
    // </summary> 
    // <param name="m_FormName">pdf form file path</param> 
    // <param name="oData">xml dataset</param> 
    // <returns>memory stream containing the pdf data</returns> 
    private MemoryStream GeneratePDF(string m_FormName, XmlDocument oData) 
    { 
    PdfReader pdfTemplate; 
    PdfStamper stamper; 
    PdfReader tempPDF; 
    Document doc; 
    MemoryStream msTemp; 
    PdfWriter pCopy; 
    MemoryStream msOutput = new MemoryStream(); 
    
    pdfTemplate = new PdfReader(m_FormName); 
    
    doc = new Document(); 
    pCopy = new PdfCopy(doc, msOutput); 
    
    pCopy.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, new PdfBoolean(true)); 
    pCopy.AddViewerPreference(PdfName.PRINTSCALING, PdfName.NONE); 
    
    doc.Open(); 
    
    for (int i = 1; i < pdfTemplate.NumberOfPages + 1; i++) 
    { 
        msTemp = new MemoryStream(); 
        pdfTemplate = new PdfReader(m_FormName); 
    
        stamper = new PdfStamper(pdfTemplate, msTemp); 
    
        // map xml values to pdf form controls (element name = control name) 
        foreach (XmlElement oElem in oData.SelectNodes("/form/page" + i + "/*")) 
        { 
         stamper.AcroFields.SetField(oElem.Name, oElem.InnerText); 
        } 
    
        stamper.FormFlattening = true; 
        stamper.Close(); 
        tempPDF = new PdfReader(msTemp.ToArray()); 
        ((PdfCopy)pCopy).AddPage(pCopy.GetImportedPage(tempPDF, i)); 
        pCopy.FreeReader(tempPDF); 
    } 
    
    doc.Close(); 
    
    return msOutput; 
    } 
    
  3. 保存文件或文件發佈到你的ASP.Net頁面的響應

0

您還可以使用iTextSharp的填寫XML數據爲讀取器擴展啓用形式。有您需要正確設置兩件事情:

  1. 設置PdfReader.unethicalreading = true防止BadPasswordException。
  2. 設置追加模式在PdfStamper的構造函數,否則ADOBE READER擴展簽名變得破碎和Adobe Reader將顯示如下消息:「這個文件中包含的某些權利,以使在Adobe Reader特殊功能的文件已。自創建以來已更改,這些權利已不再有效,請聯繫作者以獲取本文檔的原始版本。「

因此,所有你需要做的是這樣的:

PdfReader.unethicalreading = true; 
using (var pdfReader = new PdfReader("form.pdf")) 
{ 
    using (var outputStream = new FileStream("filled.pdf", FileMode.Create, FileAccess.Write)) 
    { 
     using (var stamper = new iTextSharp.text.pdf.PdfStamper(pdfReader, outputStream, '\0', true)) 
     { 
      stamper.AcroFields.Xfa.FillXfaForm("data.xml"); 
     } 
    } 
} 

How to fill XFA form using iText?