1

WkHtmlToPdf を使用して、html から pdf に変換しています。これで、リクエストに応じてすべてのフォーム フィールドも編集できるようになりました。Html を Pdf に変換する際に WkHtmlToPdf にバグがあるため、すべてのフォーム フィールドのプロパティが Visible Not Printable になります。

この問題を回避するために、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 を使用して pdf に変換される html のチェック ボックスはほとんどありません。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 を使用して新しいチェック ボックスを生成した場合でも、既存のチェック ボックスを正確に置き換えるにはどうすればよいですか?

私の話を読んでくれてどうもありがとう..

4

2 に答える 2

1

wkHtmltoPdfチェックボックスをITextSharpに置き換えることで、この問題を解決しました。私はそれを詳細に答えていますそれはあなたの時間を節約するかもしれません

            /// <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;
    }
于 2012-11-08T04:50:54.193 に答える
1

これは、CSS 疑似要素を使用した私のソリューションです。

<style>
label.checkbox:before {
    content: "☐ ";
}
label.checkbox.checked:before {
    content: "☑ ";
}
</style>
<label class="checkbox checked">Yes</label>
<label class="checkbox">No</label>
于 2016-12-22T05:51:11.773 に答える