使用iTextSharp在两个元素之间插入元素 [英] Insert Element between two elements with iTextSharp

查看:80
本文介绍了使用iTextSharp在两个元素之间插入元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to add an extra Table between two tables in a pdf file.

之间添加元素

需要考虑的事项:


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

  • The Blue and the Red one always have a fixed height.

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

The Green table height between different file may change and after adding the Red element in the middle, we may need two pages.

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

What I know? I know how to make a table and add it to a pdf file.

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

My Question: Is it possible to move the Green Element and add the Red one between? How?

推荐答案

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

As you say that you know how to make a table and add it to a pdf file and that the Blue and the Red one always have a fixed height, let's assume


  • 你已经在单独的PDF中为红色部分创建了表格,

  • 您已确定 y 坐标,在该坐标处拆分输入文档以插入红色部分,以及

  • 您还确定了要插入的表所在的单独PDF中的 y 坐标。

  • you have already created the table for the red part in a separate PDF,
  • you have determined the y coordinate at which to split the input document to insert the red part, and
  • you also have determined between which y coordinates in the separate PDF the table to insert is located.

因此,问题减少到


  • 将输入文档页面剪切为三个条带,


    • 包含蓝框的拆分 y 坐标上方的条带

    • 条纹在分割的 y 坐标下方,包含尽可能多的绿色框,插入红色框后仍然适合该页面,并且

    • 页面底部的条纹,其中包含将溢出到新的第二页的绿色框的剩余部分,

    • "cutting" the input document page into three stripes,
      • the stripe above the splitting y coordinate containing the blue box,
      • the stripe below the splitting y coordinate containing as much of the green box as will still fit on that page after insertion of the red box, and
      • the stripe at the bottom of the page containing the remainder of the green box that will overflow to a new second page,

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

      For this you can use a tool like this:

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

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

      Using this tool you can cut the stripes and paste them like this:

      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表单中的内容。

      Beware: This tool only works for content in the page content streams or content streams referenced from there, in particular not for content in annotations or XFA forms.

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

      In case of annotations one can extend the solution to associate each annotation with one of those stripes (which might be difficult for border cases) and copy stripes and associated annotations together.

      如果是XFA表单表格,这种方法将无效你首先压扁表格。

      In case of XFA form tables this approach won't work unless you flatten the form first.

      此外,现在有一些隐藏的文字可以复制并粘贴到其他地方。如果这是不可接受的,可以用更高级的 ICutter 实现替换 SimpleCutter ,这将删除(而不仅仅是隐藏)条纹之外的内容,例如使用iText PdfCleanUpProcessor

      Furthermore, there now is some hidden text which nonetheless can be copied and pasted elsewhere. If that is not acceptable, one can replace the SimpleCutter by a more advanced ICutter implementation which removes (and not only hides) content outside of stripes, e.g. using the iText PdfCleanUpProcessor.

      这篇关于使用iTextSharp在两个元素之间插入元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆