2012-11-07 82 views
1

我们正在使用WkHtmlToPdf将html从pdf转换为pdf。现在我已经根据请求编辑了所有表单域。由于在将Html转换为PDF时WkHtmlToPdf中存在一个错误,因此它将所有表单字段的属性设置为“可见不可打印”。无法打印pdf中的复选框

为了解决这个问题,我们使用ITextSharp读取由WkHtmlToPdf生成的现有PDF,并将该属性设置为每个表单字段的Visible。

这就是我正在做的是

 var pdfReader = new PdfReader(inputFilename); 

     using (var outputStream = new FileStream(outputFilename, FileMode.OpenOrCreate)) 
     { 
      var stamper = new PdfStamper(pdfReader, outputStream); 

      // Regenarating all the fileds using itextSharp. 
      // Since wkHtmltoPdf has differnt default settings for pdf form fields (Visible and not Printable) 
      var formFields = stamper.AcroFields; 
      var filedNames = formFields.Fields.Keys; 

      foreach (var keyName in filedNames) 
      { 
       formFields.SetFieldProperty(keyName, "setflags", PdfAnnotation.FLAGS_PRINT, null); 
       formFields.SetFieldProperty(keyName, "setflags", PdfFormField.FF_EDIT, null); 
       formFields.SetFieldProperty(keyName, "textsize", 8.0f, null); 
       formFields.RegenerateField(keyName); 
       } 
      } 

这解决了我的问题的所有领域,但复选框。我使用WkHtmlToPdf将html中的复选框转换为pdf。我意识到,当我尝试使用RegenerateField()(最后一行在foreach循环中)时,复选框将丢失所有属性(无论选中还是取消选中),它只显示空复选框,而且不可编辑。

为了解决这个问题,我想出了以下

if (formFields.GetFieldType(keyName).Equals(AcroFields.FIELD_TYPE_CHECKBOX)) 
{ 
        // Regenerate checkbox formfield causing it to reset all its properties 
        // including checkd/uncheked property  
        formFields.SetFieldProperty(keyName, "setflags", PdfAnnotation.FLAGS_PRINT, null); 

// Ignore the commented code as it is not working Not sure why??? and how 

        //var item = formFields.GetFieldItem(keyName); 
        //var appearance = item.GetValue(0).Get(PdfName.AS); 

        //if (appearance != null) 
        /{ 
        // if (appearance.tostring().tolower().equals("/yes")) 
        // { 
        //  formfields.regeneratefield(keyname); 

        // Not even one working when I try to set the check box status like below 
        //  success = formfields.setfield(keyname, "yes"); 
        //  success = formfields.setfield(keyname, "/yes"); 
        //  success = formfields.setfield(keyname, "/yes"); 
        //  success = formfields.setfield(keyname, "on"); 
        //  success = formfields.setfield(keyname, "1"); 


        // } 
        } 

随着代码(不包括注释)代码复选框成功保持其地位,并在生成的PDF显示。但它不是打印。我检查了复选框的属性,就像PDF中的其他字段一样。除了复选框外,所有字段(文本框)都将打印其值。 >打开PDF文档 - -

我通过检查属性>表格 - >添加/编辑域

我在做什么错在这里?除了在复选框上设置属性,我尝试使用Itextsharp构造一个全新的复选框,但我无法使用ItexSharp手动示例。以前有人做过这些吗?

即使我使用ItextSharp生成一个新的复选框,我该如何更换现有的复选框?

非常感谢我的故事..

+0

请提供展现问题的样本PDF。也许生成的PDF需要一些特殊的但可能很简单的步骤来解决一些特殊的问题。 – mkl

+0

请看这个文件。它不打印复选框并点击行为不顺利。如何解决这个问题?如果你看这个文档的预览,它会显示打印版本,如果你下载它,用选中的复选框显示我的原始文档。 https://docs.google.com/open?id=0BzdIT7JeHTmbSnNNWDBsa05VYkE – Jayee

回答

1

嗯,我用iTextSharp的替代wkHtmltoPdf复选框解决了这个问题。我回答得很详细,可能节省您的时间

  /// <summary> 
    /// By default, wkHtmlToPdf leaves pdf form fields as being "Visible but not printable". Using iTextSharp we will change them to being "Visible". 
    /// </summary> 
    private string MakePdfFormFieldsEditable(string inputFilename) 
    { 
     var outputFilename = CreateTempPdfFilename(); 

     var pdfReader = new PdfReader(inputFilename); 

     var checkedCheckBoxNames = new List<string>(); 

     using (var outputStream = new FileStream(outputFilename, FileMode.OpenOrCreate)) 
     { 
      var stamper = new PdfStamper(pdfReader, outputStream); 

      // Regenarating all the fileds using itextSharp. 
      // Since wkHtmltoPdf has differnt default settings for pdf form fields (Visible and not Printable) 
      var formFields = stamper.AcroFields; 
      var filedNames = formFields.Fields.Keys; 
      var removableFiledNames = new List<string>(); 

      foreach (var keyName in filedNames) 
      { 
       if (formFields.GetFieldType(keyName).Equals(AcroFields.FIELD_TYPE_CHECKBOX)) 
       { 
        // Since check boxes generated by WKHtmltoPdf is crapy and click behaviour is annoying 
        // we are replacing it with new checkbox 
        var item = formFields.GetFieldItem(keyName); 

        // Return "/yes" if it's checked 
        var appearance = item.GetValue(0).Get(PdfName.AS); 

        // Holds current page number information and Location on the page (Rectangle Dimentions) 
        var position = formFields.GetFieldPositions(keyName); 

        var newCheckBoxFieldname = CreateNewCheckBox(position, stamper, keyName); 

        // set newly created check box value 
        if (appearance != null && appearance.ToString().ToLower().Equals("/yes")) 
        { 
         checkedCheckBoxNames.Add(newCheckBoxFieldname); 
        } 
        // List of Check Box field names to be removed 
        removableFiledNames.Add(keyName); 
       } 
       else 
       { 
        formFields.SetFieldProperty(keyName, "setflags", PdfAnnotation.FLAGS_PRINT, null); 
        formFields.SetFieldProperty(keyName, "setflags", PdfFormField.FF_EDIT, null); 
        formFields.SetFieldProperty(keyName, "textsize", 8.0f, null); 

        formFields.RegenerateField(keyName); 
       } 
      } 

      // Removing check boxes generaed with WkHtmlToPdf 
      foreach (var oldCheckBox in removableFiledNames) 
      { 
       formFields.RemoveField(oldCheckBox); 
      } 

      stamper.Close(); 
     } 

     return checkedCheckBoxNames.Any() ? UpdateCheckBoxes(outputFilename, checkedCheckBoxNames) : outputFilename; 
    } 


    /// <summary> 
    /// Updating Check Boxe's status checked or not in input file 
    /// </summary> 
    private string UpdateCheckBoxes(string inputFilename, ICollection<string> checkedCheckBoxNames) 
    { 
     var outputFilename = CreateTempPdfFilename(); 

     var pdfReader = new PdfReader(inputFilename); 

     using (var outputStream = new FileStream(outputFilename, FileMode.OpenOrCreate)) 
     { 
      var stamper = new PdfStamper(pdfReader, outputStream); 

      var newformFields = stamper.AcroFields; 
      var newfiledNames = newformFields.Fields.Keys; 

      foreach (var keyName in newfiledNames) 
      { 
       if (!newformFields.GetFieldType(keyName).Equals(AcroFields.FIELD_TYPE_CHECKBOX)) continue; 

       if (!checkedCheckBoxNames.Contains(keyName)) continue; 

       newformFields.SetField(keyName, "On"); 
      } 

      stamper.Close(); 
     } 

     return outputFilename; 
    } 

    /// <summary> 
    /// Constructing new check box 
    /// </summary> 
    /// <param name="fieldPosition"></param> 
    /// <param name="stamper"></param> 
    /// <param name="keyName"></param> 
    /// <returns>new field name</returns> 
    private string CreateNewCheckBox(IList<AcroFields.FieldPosition> fieldPosition, PdfStamper stamper, string keyName) 
    { 
     var pageNumber = fieldPosition.First().page; 
     var locationRectangle = fieldPosition.First().position; 

     PdfContentByte canvas = stamper.GetOverContent(1); 

     // Create array with two appearances 
     var onOff = new PdfAppearance[2]; 
     onOff[0] = canvas.CreateAppearance(15, 15); 
     onOff[0].Rectangle(1, 1, 13, 13); 
     onOff[0].Stroke(); 
     onOff[1] = canvas.CreateAppearance(15, 15); 
     onOff[1].SetRGBColorFill(255, 128, 128); 
     onOff[1].Rectangle(1, 1, 13, 13); 
     onOff[1].FillStroke(); 
     onOff[1].MoveTo(1, 1); 
     onOff[1].LineTo(14, 14); 
     onOff[1].MoveTo(1, 14); 
     onOff[1].LineTo(14, 1); 
     onOff[1].Stroke(); 

     var newFieldName = keyName + "_G"; 

     // Creates new check boxes 
     var checkbox = new RadioCheckField(stamper.Writer, locationRectangle, newFieldName, "On"); 

     var field = checkbox.CheckField; 

     // Add check box field to writer 
     stamper.AddAnnotation(field, pageNumber); 

     return newFieldName; 
    } 
0

这是使用CSS伪元素我的解决方案:

<style> 
label.checkbox:before { 
    content: "☐ "; 
} 
label.checkbox.checked:before { 
    content: "☑ "; 
} 
</style> 
<label class="checkbox checked">Yes</label> 
<label class="checkbox">No</label>