使用itextsharp为下划线表单字段值

时间:2012-05-01 12:07:05

标签: c# pdf itextsharp field underline

我有一个使用itextsharp填充PDF表单字段的应用程序。

我从客户那里获得了新的要求,允许加下字段值。

我已经阅读了很多帖子,包括本网站问题的答案,但我找不到办法。

目前我的代码执行以下操作:

  1. 创建PDFStamper实例
  2. 使用stamper.AcroFields属性
  3. 获取表单字段
  4. 使用AcroFields.SetFieldRichValue()方法设置字段值。
  5. 但是当我打开PDF时,该字段为空。

    我确认该字段在PDF本身中设置为富文本。

    知道我做错了吗?

    以下是我的代码的最新内容:

                    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);
                        }
                    }
    

    编辑:

    我已根据Mark Storer的帖子将我的代码修改为一个问题(http://stackoverflow.com/questions/1454701/adding-rich-text-to-an-acrofield-in-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();
    

    但现在的问题是临时文件中没有内容....

    有什么想法吗?

2 个答案:

答案 0 :(得分:0)

上面有很多代码,差不多有400行。将来,尝试将所有内容提炼为一个非常简单且可重现的测试用例。

使用SetFieldRichValue时,您还需要将PdfStamper的{​​{1}}属性设置为AcroFields.GenerateAppearances

false

您可以阅读有关此here的更多信息以及一些注意事项和其他解决方法。

答案 1 :(得分:0)

我设法用小技巧解决它 - 我在ColumnText元素中使用了Anchor(hyperling)元素并将其定位在表单字段上方。默认情况下,锚点显示为下划线。为了在用户将鼠标悬停在锚点上时避免手标记,我将锚点的“Reference”属性设置为null。

以下是我使用的代码:

 // 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();