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

问题描述 投票:2回答:2

我正在使用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做到这一点?

c# pdf reporting-services itextsharp
2个回答
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了解更多答案。


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?

© www.soinside.com 2019 - 2024. All rights reserved.