如何从流中加载 PDF 并添加文件附件?
How to load a PDF from a stream and add a file attachment?
我正在使用 MS SQL 报表服务器网络服务生成 PDF 格式的报表:
byte[] Input;
ReportServer report = new ReportServer(serverUrl + @"/ReportExecution2005.asmx", reportPath);
Input = report.RenderToPDF(reportParamNames, reportParamValues);
此服务returns 带有 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 执行此操作?
我阅读了:
This service return a byte array with pdf file.
I need this byte array load to iTextSharp:
using (MemoryStream ms = new MemoryStream(Input))
{
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, ms);
doc.Open();
...
}
this seems ok
这不好。您想要向现有 PDF 文件添加附件,但是,您正在使用 class 和 Document
和 PdfWriter
从头开始创建 新 PDF 文档.
请阅读documentation。有一个方便的 table (6.1) 可以让您概述不同的 classes 以及何时使用它们。
我引用了 PdfReader
和 PdfStamper
class 的描述:
PdfReader
: Reads PDF files. You pass an instance of this class to one
of the other PDF manipulation classes.
PdfStamper
: Manipulates one (and only one) PDF document. Can be used
to add content at absolute positions, to add extra pages, or to fill
out fields. All interactive features are preserved, except when you
explicitly remove them (for instance, by flattening a form).
我们确定您做错了:您应该使用 PdfReader
和 PdfStamper
而不是 Document
和 PdfWriter
。现在让我们来看看 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 Whosebug 以获得更多答案。
不想创建副本,将 post 放在这里。代码似乎不起作用,它确实将某些内容附加到 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();
}
}
这与我之前的 post 相关联(因此您可以了解全貌):
How to insert an external ressource within a PDF dcument?
我正在使用 MS SQL 报表服务器网络服务生成 PDF 格式的报表:
byte[] Input;
ReportServer report = new ReportServer(serverUrl + @"/ReportExecution2005.asmx", reportPath);
Input = report.RenderToPDF(reportParamNames, reportParamValues);
此服务returns 带有 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 执行此操作?
我阅读了:
This service return a byte array with pdf file. I need this byte array load to iTextSharp:
using (MemoryStream ms = new MemoryStream(Input)) { Document doc = new Document(); PdfWriter writer = PdfWriter.GetInstance(doc, ms); doc.Open(); ... }
this seems ok
这不好。您想要向现有 PDF 文件添加附件,但是,您正在使用 class 和 Document
和 PdfWriter
从头开始创建 新 PDF 文档.
请阅读documentation。有一个方便的 table (6.1) 可以让您概述不同的 classes 以及何时使用它们。
我引用了 PdfReader
和 PdfStamper
class 的描述:
PdfReader
: Reads PDF files. You pass an instance of this class to one of the other PDF manipulation classes.
PdfStamper
: Manipulates one (and only one) PDF document. Can be used to add content at absolute positions, to add extra pages, or to fill out fields. All interactive features are preserved, except when you explicitly remove them (for instance, by flattening a form).
我们确定您做错了:您应该使用 PdfReader
和 PdfStamper
而不是 Document
和 PdfWriter
。现在让我们来看看 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 Whosebug 以获得更多答案。
不想创建副本,将 post 放在这里。代码似乎不起作用,它确实将某些内容附加到 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();
}
}
这与我之前的 post 相关联(因此您可以了解全貌): How to insert an external ressource within a PDF dcument?