【发布时间】:2018-05-15 11:05:03
【问题描述】:
是否可以为从多个 MemoryStreams 动态创建的 PDF 添加加密?
继上一个问题C# Append PDF file to MemoryStream - Cannot access a closed Stream 之后,我正在尝试添加 PDF 加密。
从我在下面提供的示例中,如果注释掉 pdfStamper.Close(); 行,我不会收到错误 Cannot access a closed Stream,但也不会对生成的 PDF 应用加密。
有人可以告诉我哪里出错了,如果可能的话如何解决我的问题?
public MemoryStream CreateMemoryStream()
{
byte[] dynamicPdfBytes;
using (var dynamicPDfMemoryStream = new MemoryStream())
{
using (var document = new Document(PageSize.A4, 25, 25, 30, 30))
{
PdfWriter.GetInstance(document, dynamicPDfMemoryStream);
document.Open();
var pdfPTable = new PdfPTable(1)
{
TotalWidth = _totalWidth,
LockedWidth = true,
SpacingBefore = _spacingBefore,
SpacingAfter = _spacingAfter
};
float[] widths = { 272f };
pdfPTable.SetWidths(widths);
var image = Image.GetInstance(HttpContext.Current.Server.MapPath("/Images/logo.png"));
image.ScaleToFit(125f, 125f);
image.Alignment = Image.RIGHT_ALIGN;
var pdfPCell = new PdfPCell(image)
{
Border = 0,
HorizontalAlignment = Element.ALIGN_RIGHT
};
pdfPTable.AddCell(pdfPCell);
document.Add(pdfPTable);
}
dynamicPdfBytes = dynamicPDfMemoryStream.ToArray();
}
byte[] pdfBytes;
using (var pdfReader = new PdfReader(HttpContext.Current.Server.MapPath("/Documents/Test.pdf")))
{
using (var pdfMemoryStream = new MemoryStream())
{
var pdfStamper = new PdfStamper(pdfReader, pdfMemoryStream);
var acroFields = pdfStamper.AcroFields;
acroFields.SetField("TestField", "This is a test");
pdfStamper.FormFlattening = true;
pdfStamper.Close();
pdfBytes = pdfMemoryStream.ToArray();
}
}
var files = new List<byte[]> { dynamicPdfBytes, pdfBytes };
byte[] array;
using (var arrayMemoryStream = new MemoryStream())
{
var document = new Document(PageSize.A4, 25, 25, 30, 30);
var pdfWriter = PdfWriter.GetInstance(document, arrayMemoryStream);
document.Open();
var directContent = pdfWriter.DirectContent;
foreach (var bytes in files)
{
var pdfReader = new PdfReader(bytes);
var pdfStamper = new PdfStamper(pdfReader, arrayMemoryStream);
pdfStamper.SetEncryption(null, _password, PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_128);
var numberOfPages = pdfReader.NumberOfPages;
for (var i = 1; i <= numberOfPages; i++)
{
document.NewPage();
var page = pdfWriter.GetImportedPage(pdfReader, i);
directContent.AddTemplate(page, 0, 0);
}
pdfStamper.FormFlattening = true;
pdfStamper.Close();
}
document.Close();
array = arrayMemoryStream.ToArray();
}
var memoryStream = new MemoryStream();
memoryStream.Write(array, 0, array.Length);
memoryStream.Position = 0;
return memoryStream;
}
任何帮助将不胜感激:-)
【问题讨论】:
-
对于这个网站上的一些用户来说,这是一种耻辱,而不是贬低用户可能没有按照他人的理想编码或可能没有正确地表达问题,也许用户可以提供更多帮助的阻碍,只是一个想法!
-
参见 stackoverflow.com/questions/28566190/… 以获取涉及表单的
PdfCopy示例。这也会有帮助:stackoverflow.com/questions/33582996/…PdfCopy对象也有一个SetEncryption()方法,如下所述:stackoverflow.com/questions/17719629/… -
请注意,您使用的是旧版本的 iText。您确实应该升级到 iText 7,因为不再支持 iText 5(或更早版本)。请不要在生产中使用您在此问题中编写的代码。如果您的客户看到您的代码,他可能会不高兴。如果您的客户没有看到您的代码,请注意 iText 是根据 AGPL 获得许可的,并且不与您的客户共享您的代码意味着您需要购买商业许可证才能使用 iText。
标签: c# pdf encryption itext