生成PDF字节数组
我有一个像这样的静态方法,并且我正在使用ITextSharp生成PDF.
I have a static method like this and I am using ITextSharp to generate PDF..
public static byte[] createPDF(string htmlstr) {
var html = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<!DOCTYPE html
PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN""
""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"">
<html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">
<head>
<title>Minimal XHTML 1.0 Document with W3C DTD</title>
</head>
<body>
" + htmlstr + "</body></html>";
// step 1: creation of a document-object
Document document = new Document(PageSize.A4, 30, 30, 30, 30);
MemoryStream msOutput = new MemoryStream();
// step 2:
// we create a writer that listens to the document
// and directs a XML-stream to a file
PdfWriter.GetInstance(document, msOutput);
// step 3: we create a worker parse the document
HTMLWorker worker = new HTMLWorker(document);
// step 4: we open document and start the worker on the document
document.Open();
worker.StartDocument();
// step 5: parse the html into the document
worker.Parse(new StringReader(html));
// step 6: close the document and the worker
worker.EndDocument();
worker.Close();
document.Close();
byte[] buffer = new byte[msOutput.Length];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = msOutput.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
msOutput.Close();
return ms.ToArray();
}
}
在调试时,通过worker.Parse(new StringReader(html))
后,MemoryStream.Length
不起作用.
When I was debugging, after I pass worker.Parse(new StringReader(html))
, the MemoryStream.Length
does not work.
我已经看到一些使用FileStream
的示例,但是我不想创建一个新文件.为什么代码会出错?
I have seen some examples out there using FileStream
but I do not want to create a new file. Why is the code erroring?
您遇到的基本问题是,默认情况下,PdfWriter
对象将关闭您正在写入的流. PdfWriter.GetInstance()
实际上返回一个可以设置其他属性的对象,并且您特别想调用该对象:
The basic problem that you are running into is that by default the PdfWriter
object will close the stream that you are writing to. PdfWriter.GetInstance()
actually returns an object that you can set additional properties and you specifically want to call:
writer.CloseStream = false;
您的MemoryStream
至byte[]
至MemoryStream
至byte[]
使我感到困惑,这只是尝试解决上述问题的一种方法吗?
Your MemoryStream
to byte[]
to MemoryStream
to byte[]
confuses me, was that just a way to try to work around the above problem?
从iTextSharp 5.0.6开始,大多数主要类(例如Document
和PdfWriter
)都实现了IDisposable
,至少对我而言,它与using
模式一起使代码更易于阅读和调试.您也不必考虑关闭太多事情.试一试:
Beginning with iTextSharp 5.0.6 most of the primary classes such as Document
and PdfWriter
all implement IDisposable
which, at least for me, along with the using
pattern makes code much easier to read and debug. You also don't have to think about closing things as much. Give this a shot:
public static byte[] createPDF(string htmlstr) {
var html = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<!DOCTYPE html
PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN""
""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"">
<html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">
<head>
<title>Minimal XHTML 1.0 Document with W3C DTD</title>
</head>
<body>
" + htmlstr + "</body></html>";
// step 1: creation of a document-object
using (Document document = new Document(PageSize.A4, 30, 30, 30, 30)) {
using (MemoryStream msOutput = new MemoryStream()) {
// step 2:
// we create a writer that listens to the document
// and directs a XML-stream to a file
using (PdfWriter writer = PdfWriter.GetInstance(document, msOutput)) {
// step 3: we create a worker parse the document
HTMLWorker worker = new HTMLWorker(document);
// step 4: we open document and start the worker on the document
document.Open();
worker.StartDocument();
// step 5: parse the html into the document
worker.Parse(new StringReader(html));
// step 6: close the document and the worker
worker.EndDocument();
worker.Close();
document.Close();
}
// Return the bytes
return msOutput.ToArray();
}
}
}