2012-05-01 30 views
0

我有一個使用itextsharp填充PDF表單域的應用程序。使用itextsharp的下劃線表單字段值

我從客戶那裏獲得了新的要求來允許強調字段值。

我已經閱讀了很多文章,包括對這個網站的問題的答案,但我無法想出辦法。

目前我的代碼執行以下操作:

  1. 創建PDFStamper實例
  2. 獲取使用stamper.AcroFields財產
  3. 使用AcroFields.SetFieldRichValue()方法來設置字段值表單字段。

但是,當我打開PDF字段是空的。

我確認該字段在PDF本身中設置爲富文本。

任何想法我做錯了什麼?

這裏是我的代碼snnipest:

   FileStream stream = File.Open(targetFile, FileMode.Create);          
       var pdfStamper = new PdfStamper(new PdfReader(sourceFile), stream);      

       // Iterate the fields in the PDF 
       foreach (var fieldName in pdfStamper.AcroFields.Fields.Keys) 
       {      
        // Get the field value of the current field 
        var fieldValue = "<?xml version=\"1.0\"?><body xmlns=\"http://www.w3.org/1999/xtml\" xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\" xfa:contentType=\"text/html\" xfa:APIVersion=\"Acrobat:8.0.0\" xfa:spec=\"2.4\"><p style=\"text-align:left\"><b><i>Here is some bold italic text</i></b></p><p style= \"font-size:16pt\">This text uses default text state parameters but changes the font size to 16.</p></body>" 

        // Set the field value 
        if (String.IsNullOrEmpty(fieldValue) == false) 
        { 
         pdfStamper.AcroFields.SetFieldRichValue(key, fieldValue); 
        } 
       } 

編輯:

我已經根據馬克·斯托勒的修訂後我的代碼問題(http://stackoverflow.com/questions/1454701 /加富文本到一個-acrofield功能於iTextSharp的)。新的代碼是:

 // Create reader to read the source file 
     var reader = new PdfReader(sourceFile); 

     // Create a stream for the generated file 
     var stream = File.Open(targetFile, FileMode.Create); 

     // Create stamper to generate the new file 
     var pdfStamper = new PdfStamper(reader, stream); 

     // Field name and value 
     var fieldName = "myfield"; 
     var fieldValue = "<?xml version=\"1.0\"?><body xfa:APIVersion=\"Acroform:2.7.0.0\" xfa:spec=\"2.1\" xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\"><p dir=\"ltr\" style=\"margin-top:0pt;margin-bottom:0pt;font-family:Helvetica;font-size:12pt\"><b>write line1 bold</b></p</body>"; 

     // Output stream for the temporary file that should contain the apearance of the field 
     var msOutput = new FileStream(@"d:\temp.pdf", FileMode.Create); 

     // string reader to read the field value 
     var textReader = new StringReader(fieldValue); 

     // Create new document 
     var document = new Document(pdfStamper.AcroFields.GetFieldPositions(fieldName)[0].position); 

     // writer for the new doucment 
     var writer = PdfWriter.GetInstance(document, msOutput); 

     // Open the document     
     document.Open(); 

     // Get elements to append to the doucment 
     var list = HTMLWorker.ParseToList(textReader, null); 

     // Append elements to the doucment 
     foreach (var element in list) 
     { 
      document.Add(element); 
     }           

     // close the documnet 
     document.Close();        

     // Append push button that contains the generated content as its apearance 
     // this approach is based on the suggestion from Mark storer that can be found in: 
     // http://stackoverflow.com/questions/1454701/adding-rich-text-to-an-acrofield-in-itextsharp 
     var button = new PushbuttonField(pdfStamper.Writer, pdfStamper.AcroFields.GetFieldPositions(fieldName)[0].position, fieldName + "_") 
          { 
           Layout = PushbuttonField.LAYOUT_ICON_ONLY, 
           BackgroundColor = null, 
           Template = pdfStamper.Writer.GetImportedPage(new PdfReader(targetFile, 1) 
          }; 
      pdfStamper.AddAnnotation(button.Field, 1);     

     pdfStamper.FormFlattening = true; 
     pdfStamper.Close(); 
     pdfStamper.Dispose(); 

但現在的問題是,臨時文件不包含任何內容....

任何想法?

+0

我不知道這是不是你的問題,但你從一個流,你也寫讀書。你的第二行代碼打開'targetFile',然後在它仍然打開時嘗試讀取它的底部。當我運行你的代碼時,我實際上遇到了異常,試圖這樣做。 –

+0

不是 - 這不是問題。我沒有檢查你說的是否與問題有關,因爲問題在代碼中早些時候開始 - 在代碼中,我創建了文件d:\ temp.pdf,它在調用document.Close()之後應該有內容。在這行代碼後,臨時文件仍然是空的,我不知道爲什麼。我假設在解決這個問題之後,將臨時文件內容應用到按鈕的模板屬性會更加直接。 –

+0

您使用的是什麼版本的iTextSharp? –

回答

0

我設法解決它有一點小技巧 - 我在ColumnText元素中使用Anchor(hyperling)元素並將其放置在表單字段上方。默認情況下,錨點以下劃線顯示。爲了避免用戶將鼠標懸停在錨點上時的手形標記,我將錨點的「引用」屬性設置爲空。

這裏是我使用的代碼:

// Create reader 
var reader = new PdfReader(sourceFilePathAndName); 

// Create stream for the target file 
var stream = File.Open(targetFilePathAndName, FileMode.Create); 

// Create the stamper 
var pdfStamper = new PdfStamper(reader, stream); 

const string fieldName = "MyField";  

// Get the position of the field 
var targetPosition = pdfStamper.AcroFields.GetFieldPositions(fieldName)[0].position; 

// Set the font 
var fontNormal = FontFactory.GetFont("Arial", 16, Font.UNDERLINE, BaseColor.BLACK); 

// Create the anchor 
var url = new Anchor("some default text", fontNormal) { Reference = null }; 

// Create the element that will contain the anchor and allow to position it anywhere on the document 
var data = new ColumnText(pdfStamper.GetOverContent(1)); 

// Add the anchor to its container 
data.SetSimpleColumn(url, targetPosition.Left, targetPosition.Bottom, targetPosition.Right, targetPosition.Top, 0, 0); 

// Write the content to the document 
data.Go(); 

pdfStamper.FormFlattening = true; 
pdfStamper.Close(); 
pdfStamper.Dispose(); 
0

上面有很多代碼,差不多有400行。將來,試着將所有東西都提煉成一個非常簡單和可重複的測試用例。

當使用SetFieldRichValue你還需要將PdfStamperAcroFields.GenerateAppearances屬性設置爲false

stamper.AcroFields.GenerateAppearances = false; 

你可以用一些注意事項和其他的變通辦法,瞭解更多關於這個here

+0

謝謝。我會檢查鏈接。我已更新我的問題,以減少代碼的長度 –

+2

它沒有解決我的問題... –