简体   繁体   English

使用 ITextSharp 将 PDF 导出到目录时损坏的文件

[英]Corrupt file when exporting PDF to a directory using ITextSharp

I am trying to generate a PDF using ITextSharp, but when I try to open it, it states it's corrupt:我正在尝试使用 ITextSharp 生成 PDF,但是当我尝试打开它时,它指出它已损坏:

错误信息

Everything seems to work fine until I open it up.在我打开它之前,一切似乎都正常。

Code:代码:

using (MemoryStream ms = new MemoryStream())
{
    Document document = new Document(PageSize.LETTER, 30, 30, 5, 5);
    PdfWriter writer = PdfWriter.GetInstance(document, ms);
    document.Open();

     // Style Code 

    #endregion

    document.Close();
    writer.Close();

    var result = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new ByteArrayContent(ms.GetBuffer())
    };

    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
    result.Content.Headers.ContentDisposition.FileName = filename;
    string filePath = @"C:\Users\mmaslova\Desktop\TEMP\" + filename;
    FileStream stream = new FileStream(filePath, FileMode.Create);

    return result;
}

Here is one error:这是一个错误:

    Content = new ByteArrayContent(ms.GetBuffer())

MemoryStream.GetBuffer() returns the whole buffer which may be much larger than the actual content. MemoryStream.GetBuffer()返回可能比实际内容大得多的整个缓冲区。 Thus, your Content often will contain a PDF with a tail of a lot of garbage bytes.因此,您的Content通常会包含带有大量垃圾字节尾部的 PDF。 As a PDF processor is expected to read a PDF from its end (where a reference to object cross references can be found), it tries to find that reference at the end of your garbage bytes.由于 PDF 处理器应该从其末尾读取 PDF(可以找到对对象交叉引用的引用),它会尝试在垃圾字节的末尾找到该引用。 This fails, so the file is corrupt.这失败了,因此文件已损坏。 (Actually Adobe Reader and other processors following its lead look for that reference in the last 1024 bytes of the file. This increases the chances of finding it but there still are enough situations in which the reference won't be found.) (实际上,Adobe Reader 和其他处理器会在文件的最后 1024 字节中查找该引用。这增加了找到它的机会,但仍然存在很多找不到引用的情况。)

You essentially have two choices:您基本上有两个选择:

  • Either you use MemoryStream.ToArray() instead.要么使用MemoryStream.ToArray()代替。 This method returns only the actual content, not unused trailing bytes.此方法仅返回实际内容,而不返回未使用的尾随字节。 The disadvantage: It creates a copy of those bytes.缺点:它会创建这些字节的副本。 Depending on the size of your PDFs and your resources, that might mean trouble.根据您的 PDF 和资源的大小,这可能意味着麻烦。
  • Or you use MemoryStream.GetBuffer() only with methods which also accept a parameter denoting the length of the actual content in that byte array, and set that parameter to MemoryStream.Length .或者,您只将MemoryStream.GetBuffer()与方法一起使用,这些方法还接受一个表示该字节数组中实际内容长度的参数,并将该参数设置为MemoryStream.Length

Eg in your case ByteArrayContent also has a constructor例如在你的情况下ByteArrayContent也有一个构造函数

public ByteArrayContent (byte[] content, int offset, int count);

( Microsoft docs on ByteArrayContent ) 关于ByteArrayContent Microsoft 文档

so you can replace所以你可以更换

    Content = new ByteArrayContent(ms.GetBuffer())

by经过

    Content = new ByteArrayContent(ms.GetBuffer(), 0, ms.Length)

The answer was that I needed to move the FileStream before document.Open();答案是我需要在 document.Open(); 之前移动 FileStream;

Answer:回答:

using (MemoryStream ms = new MemoryStream())
{
     Document document = new Document(PageSize.LETTER, 30, 30, 5, 5);
     PdfWriter writer = PdfWriter.GetInstance(document, ms);

     string filePath = @"C:\Users\mmaslova\Desktop\TEMP\" + filename;
     PdfWriter.GetInstance(document, new FileStream(filePath, FileMode.Create));
     document.Open(); 

     #endregion

    document.Close();
    writer.Close();

    var result = new HttpResponseMessage(HttpStatusCode.OK)
    {
    
       Content = new ByteArrayContent(ms.GetBuffer())
  
    };

    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
    result.Content.Headers.ContentDisposition.FileName = filename;

    return result;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM