【问题标题】:Merge 2 pdf byte streams using Itextsharp使用 Itextsharp 合并 2 个 pdf 字节流
【发布时间】:2011-12-25 18:28:08
【问题描述】:

我有一个方法可以返回一个 pdf 字节流(来自可填充的 pdf) 有没有一种直接的方法可以将 2 个流合并为一个流并从中生成一个 pdf?我需要运行我的方法两次,但需要将两个 pdf 放入一个 pdf 流中。谢谢。

【问题讨论】:

  • 字节流是iTextSharp制作的吗?是来自两个不同的可填写表格的单独字节流,还是一个表格?如果它们来自单一表单,您是否将它们展平?
  • 暂时忘记字节流。您的问题真的是“如何将两个 PDF 合并为一个?”
  • 这是同一个可填写的 PDF。我使用了 Itexsharp pdf 压模。现在在 asp.net 中使用它并将这个 pdf 流式传输到浏览器。所以,我还需要调用我的方法来流式传输相同的 pdf,但提供不同的数据并将 eevrything 放在一个流中。因此,同一个 PDF 将作为一个 PDF 出现两次。
  • @Chris,是的,我的问题是如何获取两个 pdf 字节流并返回一个 PDF 字节流。

标签: itextsharp


【解决方案1】:

您没有说是否要使用 PdfStamper 展平填充的表格,所以我只想说您必须在尝试合并之前展平他们。这是一个有效的 .ashx HTTP 处理程序:

<%@ WebHandler Language="C#" Class="mergeByteForms" %>
using System;
using System.IO;
using System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;

public class mergeByteForms : IHttpHandler {
  HttpServerUtility Server;
  public void ProcessRequest (HttpContext context) {
    Server = context.Server;
    HttpResponse Response = context.Response;
    Response.ContentType = "application/pdf";
    using (Document document = new Document()) {
      using (PdfSmartCopy copy = new PdfSmartCopy(
        document, Response.OutputStream) ) 
      {
        document.Open();
        for (int i = 0; i < 2; ++i) {
          PdfReader reader = new PdfReader(_getPdfBtyeStream(i.ToString()));
          copy.AddPage(copy.GetImportedPage(reader, 1));
        }
      }
    }
  }
  public bool IsReusable { get { return false; } }

// simulate your method to use __one__ byte stream for __one__ PDF  
  private byte[] _getPdfBtyeStream(string data) {
// replace with __your__ PDF template
    string pdfTemplatePath = Server.MapPath(
      "~/app_data/template.pdf"
    );
    PdfReader reader = new PdfReader(pdfTemplatePath);
    using (MemoryStream ms = new MemoryStream()) {
      using (PdfStamper stamper = new PdfStamper(reader, ms)) {
        AcroFields form = stamper.AcroFields;
// replace this with your form field data
        form.SetField("title", data);
        // ...
// this is __VERY__ important; since you're using the same fillable
// PDF, if you don't set this property to true the second page will
// lose the filled fields.          
        stamper.FormFlattening = true;
      }
      return ms.ToArray();
    }
  }
}

希望内联 cmets 有意义。上面的_getPdfBtyeStream() 方法模拟了您的 PDF 字节流。您需要将FormFlattening 设置为true 的原因是,当您填写PDF 表单字段时,名称应该是唯一的。在您的情况下,第二页是相同的可填写 PDF 表单,因此它与第一页具有相同的字段名称,并且当您填写它们时,它们会被忽略。注释掉上面的示例行:

stamper.FormFlattening = true;

看看我的意思。

换句话说,许多用于合并 Internet 上的 PDF 的通用代码,甚至在 stackoverflow 上也不会工作(对于可填写的表单),因为没有考虑到 Acrofields。事实上,如果你看一下 stackoverflow 的 about itextsharp tag "SO FAQ & Popular" to Merge PDFs,第三条评论中提到了@Ray Cheng 正确标记的答案。

另一种合并可填写 PDF(不展平表单)的方法是重命名第二页/后续页面的表单字段,但这需要更多工作。

【讨论】:

  • 感谢九进博的回答和解释。
猜你喜欢
  • 1970-01-01
  • 2016-11-15
  • 2011-01-15
  • 2021-03-20
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多