1

使用 iTextSharp 5.3.4.0,我在使用 PdfStamper 和 MemoryStream 时遇到了困难。

MemoryStream 始终为空。

    PdfReader pdfReader = new PdfReader(Server.MapPath(@"Document.pdf"));

    MemoryStream memoryStream = new MemoryStream();

    PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, memoryStream, '\0');

    //...

    pdfStamper.Writer.CloseStream = false;
    pdfStamper.Close();

    byte[] bt = memoryStream.GetBuffer(); //.ToArray()
    pdfReader.Close();

下载项目(完整源代码)

我怎么解决这个问题?谢谢!

4

1 回答 1

4

在 Default.aspx.cs 中,您做了一些您在问题代码块中遗漏的相关操作:

PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, memoryStream, '\0');

PdfSignatureAppearance pdfSignatureAppearance = pdfStamper.SignatureAppearance;
//...
pdfSignatureAppearance.PreClose(exc);
//...

pdfStamper.Writer.CloseStream = false;
pdfStamper.Close();

每当你打电话时PdfSignatureAppearance.PreClose,,你也必须使用PdfSignatureAppearance.Close,not PdfStamper.Close,cf。方法文档:

/**
 * This is the first method to be called when using external signatures. The general sequence is:
 * preClose(), getDocumentBytes() and close().
 * <p>
 * If calling preClose() <B>dont't</B> call PdfStamper.close().
 * <p>
 * <CODE>exclusionSizes</CODE> must contain at least
 * the <CODE>PdfName.CONTENTS</CODE> key with the size that it will take in the
 * document. Note that due to the hex string coding this size should be
 * byte_size*2+2.
 * @param exclusionSizes a <CODE>HashMap</CODE> with names and sizes to be excluded in the signature
 * calculation. The key is a <CODE>PdfName</CODE> and the value an
 * <CODE>Integer</CODE>. At least the <CODE>PdfName.CONTENTS</CODE> must be present
 * @throws IOException on error
 * @throws DocumentException on error
 */
public void PreClose(Dictionary<PdfName, int> exclusionSizes) {

(来自PdfSignatureAppearance.cs

/**
 * Closes the document. No more content can be written after the
 * document is closed.
 * <p>
 * If closing a signed document with an external signature the closing must be done
 * in the <CODE>PdfSignatureAppearance</CODE> instance.
 * @throws DocumentException on error
 * @throws IOException on error
 */
public void Close() {

(来自PdfStamper.cs

原因是当您PdfStamper使用压模创建时CreateSignature(pdfReader, memoryStream, '\0'),,压模本身不会写入内存流,而是写入内部ByteBuffer(这是最终签名创建和集成所必需的)。不早于期间PdfSignatureAppearance.Close将内容ByteBuffer写入内存流。

此外,我看到你使用

byte[] bt = memoryStream.GetBuffer();

请不要!除非您确定正确解释缓冲区内容(可能包含其他垃圾数据),否则请使用

byte[] bt = memoryStream.ToArray();

反而。

于 2013-07-18T07:05:16.277 回答