2012-11-07 85 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>