为浏览器创建类型为 pdf 和 return 的 Memorystream
Create Memorystream of type pdf and return to browser
我必须创建一个包含简单文本消息的空白 PDF,然后 return 将其发送到浏览器。我不必使用任何第三方 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 1.2 等旧版本的 PDF 标准可以写成 text-like 格式。时光机 has a copy of the PDF 1.2 specification.
您可能希望从更新版本的 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);
它有:
- A
%PDF-1.2
header 如第 5.2 章所述
- 第 4 章中描述的各种 object
- 里面的字典
<< >>
如第 4.7 章所述
stream
和 endstream
之间的流,如第 4.8 章所述
- 文本 object,以
BT
开头并以 ET
结尾,如图 8.1 中所述
- 使用
Tf
进行文本字体操作,如第 8.7.3 章所述
(
和 )
之间的文本字符串,如第 4.4 章所述。我在这里使用 .NET {0}
占位符。
- 页面需要
MediaBox
定义页面大小,如第 6.4 章所述
- A
trailer
,如第 5.5 章所述,以 %%EOF
结尾,包含强制性 /Root
条目。
您有点“自下而上”地阅读此 PDF。预告片引用Object1 0
,引用页数2 0
,引用一页3 0
,引用内容4 0
.[=30] =]
我必须创建一个包含简单文本消息的空白 PDF,然后 return 将其发送到浏览器。我不必使用任何第三方 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 1.2 等旧版本的 PDF 标准可以写成 text-like 格式。时光机 has a copy of the PDF 1.2 specification.
您可能希望从更新版本的 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);
它有:
- A
%PDF-1.2
header 如第 5.2 章所述 - 第 4 章中描述的各种 object
- 里面的字典
<< >>
如第 4.7 章所述 stream
和endstream
之间的流,如第 4.8 章所述- 文本 object,以
BT
开头并以ET
结尾,如图 8.1 中所述 - 使用
Tf
进行文本字体操作,如第 8.7.3 章所述 (
和)
之间的文本字符串,如第 4.4 章所述。我在这里使用 .NET{0}
占位符。- 页面需要
MediaBox
定义页面大小,如第 6.4 章所述 - A
trailer
,如第 5.5 章所述,以%%EOF
结尾,包含强制性/Root
条目。
您有点“自下而上”地阅读此 PDF。预告片引用Object1 0
,引用页数2 0
,引用一页3 0
,引用内容4 0
.[=30] =]