使用iTextSharp在两个元素之间插入元素

时间:2018-02-05 20:48:29

标签: c# itext

我想在pdf文件中的两个表之间添加一个额外的表。

Add Element between

需要考虑的事项:

  • 蓝色和红色总是有一个固定的高度。

  • 不同文件之间的绿表高度可能会发生变化,在中间添加红色元素后,我们可能需要两页。

  • 我所知道的?我知道如何制作一张桌子并将其添加到pdf文件中。

我的问题:是否可以移动绿色元素并在之间添加红色元素?怎么样?

1 个答案:

答案 0 :(得分:2)

正如你所说知道如何制作表并将其添加到pdf文件蓝色和红色的表总是有一个固定的高度,让我们假设

  • 您已在单独的PDF中为红色部分创建了表格,
  • 您已确定 y 坐标,用于分割输入文档以插入红色部分,
  • 您还确定了要插入的表格所在的单独PDF中的 y 坐标。

因此,问题减少到

  • 将输入文档页面“剪切”为三个条带,
    • 包含蓝框
    • 的拆分 y 坐标上方的条带
    • 分割 y 坐标下方的条纹,其中包含的绿色框与插入红色框后仍然适合该页面一样多,并且
    • 页面底部的条带,其中包含将溢出到新的第二页的绿色框的其余部分,
  • 从包含要插入的红色框的单独PDF中“剪切”条带,并
  • 以所需的新订单“粘贴”这些条纹。

为此你可以使用这样的工具:

public class CutAndPasteTool
{
    readonly Document document;
    readonly PdfWriter pdfWriter;
    readonly Dictionary<string, PdfTemplate> templates = new Dictionary<string, PdfTemplate>();

    public CutAndPasteTool(Rectangle pageSize, Stream os)
    {
        document = new Document(pageSize);
        pdfWriter = PdfWriter.GetInstance(document, os);
        document.Open();
    }

    public ICutter CreateCutter(PdfReader pdfReader, int pageNumber)
    {
        return new SimpleCutter(pdfReader, pageNumber, pdfWriter, templates);
    }

    public void Paste(string name, float x, float y)
    {
        pdfWriter.DirectContent.AddTemplate(templates[name], x, y);
    }

    public void NewPage()
    {
        document.NewPage();
    }

    public void Close()
    {
        document.Close();
    }

    class SimpleCutter : ICutter
    {
        readonly PdfImportedPage importedPage;
        readonly Dictionary<string, PdfTemplate> templates;

        internal SimpleCutter(PdfReader pdfReader, int pageNumber, PdfWriter pdfWriter, Dictionary<string, PdfTemplate> templates)
        {
            this.importedPage = pdfWriter.GetImportedPage(pdfReader, pageNumber);
            this.templates = templates;
        }

        public void Cut(string name, Rectangle rectangle)
        {
            PdfTemplate template = importedPage.CreateTemplate(rectangle.Width, rectangle.Height);
            template.AddTemplate(importedPage, importedPage.BoundingBox.Left - rectangle.Left, importedPage.BoundingBox.Bottom - rectangle.Bottom);
            templates.Add(name, template);
        }
    }
}

public interface ICutter
{
    void Cut(string name, Rectangle rectangle);
}

使用此工具,您可以剪切条纹并粘贴它们:

Rectangle pageSize = PageSize.A4; // The page size of the result file
int doc1page = 1;                 // The number of the page in the input PDF
float doc1split = 600;            // The splitting y coordinate in the input PDF
int doc2page = 1;                 // The number of the page in the separate PDF
float doc2from = 700;             // The top y coordinate of the table in the separate PDF
float doc2to = 600;               // The bottom y coordinate of the table in the separate PDF

using (PdfReader reader1 = new PdfReader(...))           // The input PDF file
using (PdfReader reader2 = new PdfReader(...))           // The separate PDF file
using (Stream os = new FileStream(..., FileMode.Create)) // The stream to write the result to
{
    Rectangle doc1box = reader1.GetPageSize(doc1page);
    Rectangle doc1upper = new Rectangle(doc1box);
    doc1upper.Bottom = doc1split;
    Rectangle doc1lower = new Rectangle(doc1box);
    doc1lower.Top = doc1split;

    Rectangle doc2box = reader2.GetPageSize(doc2page);
    Rectangle doc2inset = new Rectangle(doc2box);
    doc2inset.Top = doc2from;
    doc2inset.Bottom = doc2to;

    float doc1lowerRemainHeight = pageSize.Height - doc1upper.Height - doc2inset.Height;
    float doc1lowerOverflowHeight = doc1lower.Height - doc1lowerRemainHeight;

    Rectangle doc1lowerRemain = new Rectangle(doc1lower);
    doc1lowerRemain.Bottom = doc1lowerRemain.Top - doc1lowerRemainHeight;
    Rectangle doc1lowerOverflow = new Rectangle(doc1lower);
    doc1lowerOverflow.Top = doc1lowerRemain.Bottom;

    CutAndPasteTool tool = new CutAndPasteTool(pageSize, os);

    ICutter cutterDoc1 = tool.CreateCutter(reader1, doc1page);
    cutterDoc1.Cut("Top1", doc1upper);
    cutterDoc1.Cut("Bottom1Remain", doc1lowerRemain);
    cutterDoc1.Cut("Bottom1Overflow", doc1lowerOverflow);
    ICutter cutterDoc2 = tool.CreateCutter(reader2, doc2page);
    cutterDoc2.Cut("Inset", doc2inset);

    float y = pageSize.Top;
    tool.Paste("Top1", 0, y-= doc1upper.Height);
    tool.Paste("Inset", 0, y -= doc2inset.Height);
    tool.Paste("Bottom1Remain", 0, y -= doc1lowerRemain.Height);

    tool.NewPage();

    y = pageSize.Top;
    tool.Paste("Bottom1Overflow", 0, y -= doc1lowerOverflow.Height);

    tool.Close();
}

注意:此工具仅适用于页面内容流或从中引用的内容流中的内容,尤其适用于注释或XFA表单中的内容。

如果是注释,可以扩展解决方案,将每个注释与其中一个条带(对于边框情况可能很难)相关联,并将条带和关联的注释复制在一起。

如果是XFA表格表,除非先将表格弄平,否则这种方法不起作用。

此外,现在有一些隐藏的文本可以复制并粘贴到其他地方。如果这是不可接受的,则可以通过更高级的SimpleCutter实施来替换ICutter,该实施方式会移除(并且不仅隐藏)条带之外的内容,例如:使用iText PdfCleanUpProcessor