iTextSharp:在表格单元格上的文本字段上设置文本会导致文本太宽并且被压扁

时间:2014-08-07 19:18:22

标签: c# pdf pdf-generation itextsharp

我认为这可能是一个错误,但如果有人可以提供帮助,我会感激它。我目前还有另一个问题涉及类似的问题,但我认为这个问题更能说明问题,更简单。话虽如此,我不想删除旧的,以防它增加我的等待时间。我屈服于mods来决定哪个问题更好。

这是一个示例应用程序,它创建一个pdf,然后是一个表。它向表中添加一个单元格,然后将fieldpositioningevent绑定到单元格事件。

using System;
using System.Diagnostics;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace iTextSharpTextBoxInTableCell
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a PDF with a TextBox in a table cell
            BaseFont bfHelvetica = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, false);
            Font helvetica12 = new Font(bfHelvetica, 12, Font.NORMAL, BaseColor.BLACK);

            Document doc = new Document(PageSize.LETTER, 18f, 18f, 18f, 18f);
            FileStream fs = new FileStream("TextBoxInTableCell.pdf", FileMode.Create);
            PdfWriter writer = PdfWriter.GetInstance(doc, fs);

            doc.Open();
            PdfPTable myTable = new PdfPTable(1);
            myTable.TotalWidth = 568f;
            myTable.LockedWidth = true;
            myTable.HorizontalAlignment = 0;

            TextField tf = new TextField(writer, new iTextSharp.text.Rectangle(67, 585, 140, 800), "cellTextBox");
            tf.Text = "test";
            PdfPCell tbCell = new PdfPCell(new Phrase(" ", helvetica12));
            iTextSharp.text.pdf.events.FieldPositioningEvents events =
                new iTextSharp.text.pdf.events.FieldPositioningEvents(writer, tf.GetTextField());
            tbCell.CellEvent = events;

            myTable.AddCell(tbCell);

            doc.Add(myTable);

            doc.Close();

            fs.Close();
            Process.Start("TextBoxInTableCell.pdf");
            Console.WriteLine("End Of Program Execution");
            Console.ReadLine();
        }
    }
}

以下是此字段生成后的内容:squashed

正如您所看到的,文本被压扁了。我已发布了生成的pdf here

1 个答案:

答案 0 :(得分:2)

我肯定会看到你所看到的内容,正如@mkl在你的另一篇文章中所说,问题归结为外观的BBOX条目没有设置为相同作为领域的大小。我无法在野外找到太多FieldPositioningEvents的例子,而且确实存在的例子在大多数情况下都是相互复制和粘贴的。

无论如何,如果您阅读了FieldPositioningEvents的实际代码,您会发现它可以用于页面事件以及单元格事件,这使我认为它可能用于更广泛的目的,但是这只是我的一个猜测。

一种解决方案是编写自己的IPdfPCellEvent子类。以下是FieldPositioningEvents提供的示例之后的示例,但它特定于TextFields,因为我们对设置/BBOX条目感兴趣。它有两个构造函数,一个与FieldPositioningEvents非常相似,一个PdfWriter和一个TextField,另一个只占用TextFields的最常见属性为你创造它。 CellLayout是接口契约的一部分,实际上指出了应该在哪里绘制注释。

public class SingleCellFieldPositioningEvent : IPdfPCellEvent {

    public TextField Field { get; set; }
    public PdfWriter Writer { get; set; }
    public float Padding { get; set; }

    public SingleCellFieldPositioningEvent(PdfWriter writer, TextField field) {
        this.Field = field;
        this.Writer = writer;
    }

    public SingleCellFieldPositioningEvent(PdfWriter writer, string fieldName, string text = "", BaseFont font = null, float fontSize = 14 ) {
        //The rectangle gets changed later so it doesn't matter what we use
        var rect = new iTextSharp.text.Rectangle(1, 1);

        //Create the field and set various properties
        this.Field = new TextField(writer, rect, fieldName);
        this.Field.Text = text;
        if (null == font) {
            font = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
        }
        this.Field.Font = font;
        this.Field.FontSize = fontSize;

        this.Writer = writer;
    }

    public void CellLayout(PdfPCell cell, iTextSharp.text.Rectangle rect, PdfContentByte[] canvases) {
        //Create the field's rectangle based on the current cell and requested padded
        var newRect = new PdfRectangle(rect.GetLeft(Padding), rect.GetBottom(Padding), rect.GetRight(Padding), rect.GetTop(Padding));

        //Set the appearance's rectangle to the same as the box
        Field.Box = newRect.Rectangle;

        //Get the raw field
        var tf = this.Field.GetTextField();

        //Change the field's rectangle
        tf.Put(PdfName.RECT, newRect);

        //Add the annotation to the writer
        Writer.AddAnnotation(tf);
    }
}

您可以通过两种不同的方式使用它。手动创建一个字段并设置各种属性:

//The rectangle is actually changed in the cell event so it doesn't matter what we use
TextField tf = new TextField(writer, new iTextSharp.text.Rectangle(1, 1), "cellTextBox");
tf.Text = "test";
tf.Font = bfHelvetica;
tf.FontSize = 14;
PdfPCell tbCell = new PdfPCell(new Phrase(" ", helvetica12));
tbCell.CellEvent = new SingleCellFieldPositioningEvent(writer, tf);

或者只是传递属性:

PdfPCell tbCell = new PdfPCell(new Phrase(" ", helvetica12));
tbCell.CellEvent = new SingleCellFieldPositioningEvent(writer, "cellTextBox", "test", bfHelvetica, 14);
myTable.AddCell(tbCell);