我必须创建一个带有简单文本消息的空白PDF,并将其返回到浏览器。我不必使用任何第三方PDF库,如iTextSharp、PDFDocument等。
我正在使用MemoryStream
,但生成了一个损坏的PDF。
MemoryStream ms = new MemoryStream();
ms.Write(System.Text.Encoding.Unicode.GetBytes("test message"), 0, System.Text.Encoding.Unicode.GetBytes("test message").Length);
Response.AddHeader("Content-Disposition", "attachment;filename=" + id.ToString() + ".pdf");
return File(ms.ToArray(), "application/pdf");
我缺少什么?
您基本上已经创建了一个TXT文件,并将其发送到浏览器,声明为PDF。
PDF有自己的文件格式。PDF标准的旧版本,如PDF 1.2,可以用类似文本的格式编写。Wayback Machine有一份PDF 1.2规范的副本。
您可能想要从PDF标准的新版本中获益。也许你不想花时间阅读和理解400页。此外,你不想要巨大的字符串模板,而是一种更具表现力的创建PDF文件的方式。所以,图书馆可以为你节省很多时间和精力。
不管怎样,你可以阅读该规范并想出类似的东西
string template = @"
%PDF-1.2
4 0 obj << >>
stream
BT/ 12 Tf({0})' ET
endstream
endobj
3 0 obj << /Type /Page /Parent 2 0 R /Contents 4 0 R >> endobj
2 0 obj << /Kids [3 0 R ] /Count 1 /Type /Pages /MediaBox [ 0 0 99 99 ] >> endobj
1 0 obj << /Pages 2 0 R /Type /Catalog >> endobj
trailer << /Root 1 0 R >>
%%EOF
";
string text = "Text message";
string pdf = string.Format(template, text);
它有:
- 如第5.2章所述的
%PDF-1.2
标头 - 第4章中描述的各种对象
<< >>
中的词典,如第4.7章所述stream
和endstream
之间的流,如第4.8章所述- 如图8.1所示,一个以
BT
开头、以ET
结尾的文本对象 - 如第8.7.3章所述,使用
Tf
进行文本字体操作 (
和)
之间的文本字符串,如第4.4章所述。我在这里使用.NET{0}
占位符- 具有所需
MediaBox
的页面,定义页面大小,如第6.4章所述 - 如第5.5章所述的
trailer
,以%%EOF
结尾,包含一个强制性的/Root
条目
你有点读这个PDF"自下而上";。尾部指代对象1 0
,其指代页面2 0
,其指一个页面3 0
,其指内容4 0
。