iText(夏普) - 表格单元格

时间:2017-06-12 17:20:57

标签: pdf itext

我在iTextSharp生成的PDF文件中绘制了一个等式。没有什么复杂的,比如:

x-y
--- + 3
 z

但有两个有趣的警告:

  1. 在表格单元格中绘制等式以及一些文本
  2. 该表格采用结构化文件(章节和章节)绘制,因此我不会提前知道要绘制单元格的位置。
  3. 我通过在模板中绘制等式来解决这个问题:

    section.Add(new Paragraph("Here comes my equation in a table"));
    
    PdfPTable outerTable = new PdfPTable(2);
    outerTable.AddCell(new PdfPCell(new Phrase(new Chunk("Look at the next cell"))));
    
    PdfTemplate template = pdfWriter.DirectContent.CreateTemplate(bounds.Width, bounds.Height);
    draw_my_equation_into(template);
    Image image = iTextSharp.text.Image.GetInstance(template);
    
    PdfPTable innerTable = new PdfPTable(1);   // Inner table, inside cell (1, 0) in my outer table.
    innerTable.AddCell(new PdfPCell(new Phrase(new Chunk("Here is my equation:"))));
    innerTable.AddCell(new PdfPCell(image));
    
    outerTable.AddCell(innerTable);
    
    section.Add(outerTable);
    chapter.Add(section);
    

    工作正常。好东西。

    但是现在我意识到我想给我的文档的读者一些帮助,如果他们想要的话,可以帮助理解这个等式,所以如果他们将鼠标悬停在等式上,我想要出现一些文本,让他们跳到偶然更多解释,如果他们点击等式。我知道这样做的唯一方法是在块as seen here上使用PushbuttonField和泛型标记。

    但我无法弄清楚如何在这种情况下添加一个PushbuttonField,我没有一个Chunk来调用SetGenericTag(),我也不知道该方程在页面上的位置。

    创建PdfTemplate的方法是错误的吗?我是否需要使用其他方法创建我的方程式,因此我可以获得一个Chunk并调用SetGenericTag()?或者有没有办法找出方程的位置,以便我可以创建我的PushbuttonField?

    =====稍后添加

    我刚刚意识到我可以稍后移动模板的绘图,我可以在OnCloseDocument()处理程序中进行绘图,我假设在那时它完成了所有布局,因此它确切知道模板的位置正在被吸引。但是我不知道如何询问模板在哪里被绘制......

1 个答案:

答案 0 :(得分:0)

我最终得到了一个相当复杂但功能性的解决方案,基于将CellEvent添加到包含等式的单元格。它假定包含等式的单元格仅包含 等式。这不是一个糟糕的假设,但我想要一个更通用的解决方案。

    class EquationDrawer : IPdfPCellEvent
    {
        IEquation m_equate;
        PdfTemplate m_template;

        public EquationDrawer(IEquation equate, PdfTemplate template)
        {
            m_equate = equate;
            m_template = template;
        }
        void IPdfPCellEvent.CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
        {
            // Draw the equation into the template
            m_equate.Draw(m_template);

            // Calculate the actual position on the page of where
            // the equation will be drawn by taking the cell rectangle
            // and insetting by the cell padding
            Rectangle bounds = m_equate.Bounds;
            Rectangle draw = new Rectangle(position.Left + cell.PaddingLeft,
                position.Bottom + cell.PaddingBottom,
                position.Left + cell.PaddingLeft + bounds.Width,
                position.Top - cell.PaddingTop);

            // Calculate where, in the overall equation, is the text
            // that I want to add a button to
            Rectangle text = m_equate.WhereIsMyText(draw);

            CreatePushbutton(m_template.PdfWriter, text, m_tooltip, m_dest);
        }

        void CreatePushbutton(PdfWriter writer, Rectangle rect, string tooltip, string localDestination)
        {
            PdfContentByte cb = writer.DirectContentUnder;
            cb.SaveState();
            cb.SetColorStroke(BaseColor.BLUE);
            cb.SetLineWidth(0.5); 
            cb.SetLineDash(3, 2);
            cb.MoveTo(rect.Left, rect.Bottom - dashOffsetY);
            cb.LineTo(rect.Right, rect.Bottom - dashOffsetY);
            cb.Stroke();
            cb.RestoreState();

            PushbuttonField button = new PushbuttonField(writer, rect, "DefineButton-" + (++NumButtons));
            PdfFormField field = button.Field;
            field.Action = PdfAction.GotoLocalPage(localDestination, false);
            field.UserName = tooltip;
            writer.AddAnnotation(field);
        }
    }