【问题标题】:iTextSharp: Setting text on textfield that is on a table cell results in text being too wide and squashediTextSharp:在表格单元格上的文本字段上设置文本会导致文本太宽和被压扁
【发布时间】:2014-08-07 19:18:21
【问题描述】:

我认为这可能是一个错误,但如果有人可以提供帮助,我将不胜感激。我目前还有一个处理类似问题的未解决问题,但我认为这个问题更好地说明了这个问题,而且也更简单。话虽如此,我不想删除旧的,以防它增加我的等待时间。我让模组决定哪个问题更好。

这是一个创建 pdf 的示例应用程序,然后是一个表格。它将一个单元格添加到表格中,然后将字段定位事件与单元格事件联系起来。

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

这是该字段生成时的样子:

如您所见,文本被压扁了。我已经发布了生成的 pdf here.

【问题讨论】:

    标签: c# pdf pdf-generation itextsharp


    【解决方案1】:

    我肯定看到了您所看到的,正如@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);
    

    【讨论】:

    • 壮观的答案。我几乎希望他们能将其合并到代码中,尽管诚然,这有点不常见。谢谢!
    • 我只是专门处理/BBox 值,实际上可能需要设置其他几种外观状态。如果你遇到这些,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多