问题
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();
}
}
When I was debugging, after I pass worker.Parse(new StringReader(html))
, the MemoryStream.Length
does not work.
I have seen some examples out there using FileStream
but I do not want to create a new file. Why is the code erroring?
回答1:
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;
Your MemoryStream
to byte[]
to MemoryStream
to byte[]
confuses me, was that just a way to try to work around the above problem?
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();
}
}
}
来源:https://stackoverflow.com/questions/21469028/generating-pdf-byte-array