如何从流中加载PDF并添加文件附件?

时间:2015-01-29 08:48:21

标签: c# pdf reporting-services itextsharp

我使用MS SQL Report Server Web服务生成PDF格式的报告:

byte[] Input;
ReportServer report = new ReportServer(serverUrl + @"/ReportExecution2005.asmx", reportPath);
Input = report.RenderToPDF(reportParamNames, reportParamValues);

此服务返回带有pdf文件的字节数组。

我需要将此字节数组加载到iTextSharp:

using (MemoryStream ms = new MemoryStream(Input)) {
    Document doc = new Document();
    PdfWriter writer = PdfWriter.GetInstance(doc, ms);
    doc.Open();
    ...
}

这似乎没问题,但我正在尝试为此PDF添加附件:

PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(writer, xmlInputFile, xmlFileDisplayName, null);
writer.AddFileAttachment(pfs);

这似乎也可以,但是当我将流保存到文件时,生成的pdf不正确。

请注意,文件附件将始终是一个XML文件,我需要在内存中创建,永远不会在文件系统中。我怎么能用iTextSharp做到这一点?

2 个答案:

答案 0 :(得分:3)

我看了:

  

此服务返回带有pdf文件的字节数组。   我需要这个字节数组加载到iTextSharp:

using (MemoryStream ms = new MemoryStream(Input))
{
  Document doc = new Document();
  PdfWriter writer = PdfWriter.GetInstance(doc, ms);
  doc.Open();
  ...
}
     

这似乎没问题

这是确定。您想要为现有PDF文件添加附件,但是,您正在使用DocumentPdfWriter这些类来从头创建新的PDF文档

请阅读documentation。有一个方便的表(6.1),可以让您概览不同的类以及何时使用它们。

我引用了PdfReaderPdfStamper类的描述:

  

PdfReader:读取PDF文件。您将此类的实例传递给一个   其他PDF操作类。

     

PdfStamper:处理一个(且只有一个)PDF文档。可以用   在绝对位置添加内容,添加额外页面或填充   外地。除非您,否则将保留所有交互式功能   明确删除它们(例如,通过展平表单)。

我们已经确定您做错了:您应该使用PdfReaderPdfStamper而不是DocumentPdfWriter。现在让我们来看看some examples

PdfReader reader = new PdfReader(pdf_bytes);
using (var ms = new MemoryStream()) {
    using (PdfStamper stamper = new PdfStamper(reader, ms)) {
        PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(
            stamper.Writer, xmlInputFile, xmlFileDisplayName, null);
        stamper.AddFileAttachment(pfs);
    }
    reader.Close();
    return ms.ToArray();
}

如您所见,我们使用保存在内存中的字节创建PdfReader实例。然后,我们使用PdfStamper创建一个新的MemoryStream,我们使用这些字节。

请查看The Best iText Questions on StackOverflow以获取更多答案。

答案 1 :(得分:0)

不想创建重复项,将其发布到此处。该代码似乎无法正常工作,尽管文件附件最终损坏,但它确实将某些内容附加到pdf。在我的情况下,尝试使用URL:

    static void Main(string[] args)
    {
        byte[] file_bytes = File.ReadAllBytes(@"./legit.pdf");
        byte[] modified_bytes = GeneratePDFByte(file_bytes);
        File.WriteAllBytes(@"./modified.pdf", modified_bytes);
    }

    private static byte[] GeneratePDFByte(byte[] pdf_bytes)
    {
        PdfReader reader = new PdfReader(pdf_bytes);
        using (var ms = new MemoryStream())
        {
            using (PdfStamper stamper = new PdfStamper(reader, ms))
            {
                PdfFileSpecification pfs = PdfFileSpecification.Url(stamper.Writer, "https://itextpdf.com/sites/default/files/styles/max_1300x1300/public/2019-08/Octocat.png");
                stamper.AddFileAttachment("file", pfs);
            }
            reader.Close();
            return ms.ToArray();
        }
    }

这与我的上一篇文章相关(因此您可以看到完整图片): How to insert an external ressource within a PDF dcument?