1

我在使用 ITextSharp 创建一些推送到 MVC 浏览器应用程序的表和图像时遇到问题。我想我已经把它缩小到使用 WriteRowsSelected 添加表的范围内。

这是我的代码:

PDFEngine.cs

  private byte[] BuildDocument(MemoryStream documentStream, IEnumerable<CustomPdfData> documents, bool addVoid, float defaultMagnification)
    {

       using (var stream = new MemoryStream())
        {
        var finishedDocument = new Document(new Rectangle(612f, 792f));

        var writer = PdfWriter.GetInstance(finishedDocument, stream);
        writer.ViewerPreferences = PdfWriter.HideWindowUI;
        writer.ViewerPreferences = PdfWriter.HideMenubar;

        // Open the Document for writing
        finishedDocument.Open();


        var zoomer = PdfAction.GotoLocalPage(1, new PdfDestination(PdfDestination.XYZ, -1, -1, defaultMagnification), writer);

        writer.SetOpenAction(zoomer);



        foreach (var document in documents)
        {


            if (document.IsNewPage)
            {
                finishedDocument.NewPage();
            }

            var results = TableEngine.BuildDocument(document);

            // Build Canvas for Table
            //PdfContentByte canvas = writer.DirectContent;
            //canvas.SetTextMatrix(50, 50);

            // Add each table to the canvas at specified coordinates
            for (int tableCounter = 0; tableCounter < results.ITextTables.Count; tableCounter++)
            {
                PdfContentByte canvas = writer.DirectContent;
                canvas.SetTextMatrix(50, 50);

                var xAxis = results.PdfTables[tableCounter].XPosition;
                var yAxis = results.PdfTables[tableCounter].YPosition;
                results.ITextTables[tableCounter].WriteSelectedRows(0, results.PdfTables[tableCounter].ColumnSize, xAxis, yAxis, writer.DirectContent);
            }




        }

        finishedDocument.Close();
        documentStream.Close();
        return stream.ToArray();
    }

CheckBuilder.cs

  /// <summary>
    /// Used to create the fake checks needed for printing to a client
    /// </summary>
    /// <param name="checks">Checks to push to Builder</param>
    /// <returns></returns>
    public byte[] GetFakeChecks(List<HandsCheck> checks)
    {

        var doc = BuildCheck(checks, true, true);
        return CreatePdf(doc, 0.5f, false);
    }

DisplayChecks.cshtml

 <object id="WebBrowser1"  width="615" height="790"  data= "@Url.Action("GetPdfData")" type="application/pdf" />

家庭控制器.cs

    public FileContentResult GetPdfData()
    {
        int numberofChecks = int.Parse(Workspace.Get<string>("numberofChecks"));

     var pdfCreator = new CheckBuilder();

            var checks = GetAllChecks();
            var newList = new List<Check>();

            for (int counter = 0; counter < numberofChecks; counter++)
            {
                newList.Add(checks[counter]);
            }

            var rawData = pdfCreator.GetFakeChecks(newList);

            return File(rawData, "application/pdf");


        return null;
    }

奇怪的是,它似乎只在我添加超过1 个表时才会发生。有谁知道每张画布是否有任何限制?有谁知道进一步调试可能导致此问题的任何方法?

4

1 回答 1

3

您在这里引入了 PDF 语法错误:

PdfContentByte canvas = writer.DirectContent;
canvas.SetTextMatrix(50, 50);

使用DirectContent,您可以获取一个对象,该对象允许您将 PDF 语法直接写入内容流。紧接着,你引入了一个文本状态操作符。这是非法的 PDF 语法:

  1. 文本状态运算符仅在文本对象内部有效;即:在BT( BeginText()) 和ET( EndText) 运算符之间)。
  2. 为什么需要设置文本矩阵?该行没有意义,因为您在writeSelectedRows()方法中定义了表格的位置。

长话短说:删除canvas.SetTextMatrix(50, 50);,您的 PDF 中至少会少一个语法错误。

我刚刚检查了 iText 代码库,通常您的代码应该抛出“不平衡文本状态”异常。如果没有,要么“健全性检查”不再起作用,要么您使用的是过时的 iTextSharp 版本。

更新

评论1:

ISO-32000-1 将文本状态定义为图形状态的子集。在图形状态下,您可以更改所有图形对象的线宽、笔触颜色、填充颜色、“当前变换矩阵”等...您可以在图形状态下绘制线条、形状等,但不能绘制文本。

文本状态是为文本保留的:您更改文本矩阵、定义前导、字体……然后“显示”文本。在 BT 和 ET 块之外使用文本状态运算符是非法的;例如:仅在图形状态下更改文本矩阵是没有意义的,因为在 BT/ET 序列之外没有文本。嵌套 BT 和 ET 对象也是非法的。

评论 2:

就个人而言,我使用 Adob​​e Acrobat(预检功能)来检查损坏的 PDF 的语法。这是最简单的方法,但这并不意味着它很容易。尽管我非常了解 ISO-32000-1,但即使我也并不总是能理解错误消息。

有时 Acrobat 无法打开 PDF 文件,错误是“未知”,或者 Acrobat 是“无法分析 PDF 语法”。参见例如当盖章文件时 - 丹麦字符消失并且 PDF 变得无效,这是我几天前回答的一个问题。在这种情况下,我尝试使用 iText RUPS 并从内部检查 PDF。在最坏的情况下,您需要在纯文本编辑器中检查 PDF(例如,因为即使 RUPS 也无法打开文件)。

评论 3:

使用 时writeSelectedRows(),iText(Sharp) 会自动添加一个BTandET运算符。某些版本可能会省略BTif aBT已经存在;如果缺少a,某些版本的 iTextSharp 可能会BT在使用时添加 a。setTextMatrix()BT

长话短说:iText(Sharp) 有时会尝试修复由于编程错误而导致的问题。这些修复并不能完全证明,因为 iText(Sharp) 不能总是猜测开发人员的意图。结果,修复经常失败。士气:应确保不引入 PDF 语法错误。

于 2013-08-20T16:55:23.113 回答