[英]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:您基本上有两个选择:
MemoryStream.ToArray()
instead.MemoryStream.ToArray()
代替。 This method returns only the actual content, not unused trailing bytes.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.