I have an set of PDF files created before using different system.
Those are styled correctly, (using Arial font, bold and normal) - PDF contains Swedish characters, and everything works when I print it.
However, I've been working on an solution to not show the pdf file itself to the user, just start the print dialogue. I have used iTextSharp to include JS code what will automatically print the PDF once started.
Method that adds the JS to the provided file and sends it to the user:
protected void StreamPdf(string pdfSource)
{
var outputStream = new MemoryStream();
var pdfReader = new PdfReader(pdfSource);
var pdfStamper = new PdfStamper(pdfReader, outputStream);
//Add the auto-print javascript
var writer = pdfStamper.Writer;
writer.AddJavaScript(GetAutoPrintJs());
pdfStamper.Close();
var content = outputStream.ToArray();
outputStream.Close();
Response.ContentType = "application/pdf";
Response.BinaryWrite(content);
Response.End();
outputStream.Close();
outputStream.Dispose();
}
Now the thing is - after writing the file back using response, I am loosing the formatting - text that was bold before now is normal, and regional characters are lost (displaying empty squares instead).
Is there any possibility to preserve the formatting?
Related
I'm trying to build pdfs to digitize our reporting system at my company. I've used iTextSharp and so far it looks great but my margins don't seem to be working properly. I've set the margins to a config file and the left and right margins are working great, but my paragraph seems to start about 30% down the page regardless of the top and bottom margin. Here's the code I'm using:
public int PrintPdf()
{
//Getting the path
//Path.GetFileNameWithoutExtension("Test_Doc_Print") + ".pdf");
object OutputFileName = this._path;
//Making the PDF Doc
iTextSharp.text.Document PDFReport = new iTextSharp.text.Document
(
PageSize.A4.Rotate(),
/*this._left,
this._right,
this._top,
this._bottom*/
10,
10,
10,
10
);
//Setting The Font
string fontpath = #"C:\Windows\Fonts\";
BaseFont monoFont = BaseFont.CreateFont(fontpath + "Consola.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
Font fontPDF = new Font(monoFont, this._fontSize);
// create file stream for writing the PDF
FileStream fs = new FileStream(this._path, FileMode.Create, FileAccess.ReadWrite);
//FileStream fs = new FileStream(#"c:\\Reportlocation", FileMode.Create);
// Create an FCFC scan object to convert TextToPrint page at a time
FCFCScanner page = new FCFCScanner(this._text);
// Create PDF writer and associate with file stream
//iTextSharp.text.pdf.PdfWriter writer = new iTextSharp.text.pdf.PdfWriter.GetInstance(PDFReport, fs);
PdfWriter writer = PdfWriter.GetInstance(PDFReport, fs);
//Opening the PDF Doc
PDFReport.Open();
//Load each page from the string into the PDF
page.NextPage();
do
{
if (page.PageLength > 0)
{
Paragraph prg = new Paragraph(page.Page, fontPDF);
PDFReport.Add(prg);
PDFReport.NewPage();
page.NextPage();
}
} while (page.MorePages);
PDFReport.Close();
return (0);
}
I've set the margins to 10 (hardcoded for now) to show what I'm working with. This program should read a string that I send it from my StringBuider class.
It's designed to receive one page of text at a time and to convert it into a PDF document.
Ok, so the problem: when the page is built, the first paragraph doesn't begin at the top margin. If I reduce the margin, it doesn't shift the paragraph up to the new margin. It's causing my PDFs to be much longer as the text that fits easily on a printer page takes two PDF pages. Any help with getting my paragraph to simply begin at the top margin would be really appreciated.
I'm relatively new to programming and this is my first post, so if you need more information, let me know and I'll add more info.
In vb.net I need to print the contents showing in a browser control to printer.
I have used Gecko web-browser control in winform application and there is no direct way to print the page's contents.
Either way to print direct using InnerHtml or converting that html to pdf and then printing the pdf document.
currently I am using a third party library `ItextSharpe' but it gives errors.
public byte[] GetPDF(string pHTML) {
byte[] bPDF = null;
MemoryStream ms = new MemoryStream();
TextReader txtReader = new StringReader(pHTML);
// 1: create object of a itextsharp document class
Document doc = new Document(PageSize.A4, 25, 25, 25, 25);
// 2: we create a itextsharp pdfwriter that listens to the document and directs a XML-stream to a file
PdfWriter oPdfWriter = PdfWriter.GetInstance(doc, ms);
// 3: we create a worker parse the document
HTMLWorker htmlWorker = new HTMLWorker(doc);
// 4: we open document and start the worker on the document
doc.Open();
htmlWorker.StartDocument();
// 5: parse the html into the document
htmlWorker.Parse(txtReader);
// 6: close the document and the worker
htmlWorker.EndDocument();
htmlWorker.Close();
doc.Close();
bPDF = ms.ToArray();
return bPDF;
}
Byte[] bytes;
bytes = GetPDF(browse.Document.Body.InnerHtml);
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
System.IO.File.WriteAllBytes(testFile, bytes);
but throws errors while parsing.
Unable to cast object of type 'iTextSharp.text.html.simpleparser.CellWrapper' to type 'iTextSharp.text.Paragraph'.
I have seen different examples over web but this is totally different, the examples or duplicate answer is about to export panels or grids but this is dynamic HTML and i need to convert it to PDF or print directly the client area.
I've just added the iTextSharp XMLWorker nuget package (and its dependencies) to my project and I'm trying to convert the HTML from a string into a PDF file, even though no exceptions are being thrown, the PDF file is being generated with two blank pages. Why?
The previous version of the code was using just iTextSharp 5.5.8.0 with HTMLWorker and ParseList method, then I switched to
Here is the code I'm using:
public void ExportToPdf() {
string htmlString = "";
Document document = new Document(PageSize.A4, 40, 40, 40, 40);
var memoryStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(document, memoryStream);
document.Open();
htmlString = sbBodyMail.ToString();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, new StringReader(htmlString));
document.Close();
DownloadFile(memoryStream);
}
public void DownloadFile(MemoryStream memoryStream) {
//Clears all content output from Buffer Stream
Response.ClearContent();
//Clears all headers from Buffer Stream
Response.ClearHeaders();
//Adds an HTTP header to the output stream
Response.AddHeader("Content-Disposition", "attachment;filename=Report_Diagnosis.pdf");
//Gets or Sets the HTTP MIME type of the output stream
Response.ContentType = "application/pdf";
//Writes the content of the specified file directory to an HTTP response output stream as a file block
Response.BinaryWrite(memoryStream.ToArray());
//Response.Write(doc);
//sends all currently buffered output to the client
Response.Flush();
//Clears all content output from Buffer Stream
Response.Clear();
}
If I place document.Add(new Paragraph("Just a test")); right before document.Close(); the paragraph is rendered in the second page, but the rest of the document still is blank.
UPDATE
I've changed the HTML in the htmlString variable to just a DIV and a TABLE and it worked. So, now the question becomes: how do I know what part of the HTML is causing some error in the XMLWorker?
I've figured out that XMLWorkerHelper was having trouble with DIV width attribute (even set on style attribute) and unfortunately it doesn't throw any exception to help you on this.
I found this answer from iTextSharp's developer that says that centering a table isn't supported yet, so I'm assuming this is not supported too.
I am using the following code for generating a PDF file.
It is working good, but now i want to generate 4 PDF's at the same time.
I tried by again initiating Document & repeating the whole code for generating 2nd PDF report, But it generates only 1 PDF.
var document = new Document(PageSize.A4, 50, 50, 25, 25);
// Create a new PdfWrite object, writing the output to a MemoryStream
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
// Open the Document for writing
document.Open();
string contents = System.IO.File.ReadAllText(Server.MapPath("~/Reports/Original.html"));
var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(contents), null);
foreach (var htmlElement in parsedHtmlElements)
document.Add(htmlElement as IElement);
document.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", string.Format("attachment;filename=Receipt-{0}.pdf", "Report"));
Response.BinaryWrite(output.ToArray());
return View();
How to generate multiple PDF's?
You are outputting the bytes as a response, so you would never be able of generating 2 different files in one response. Only one response per request.
If you want the user to download 2 different PDFs at the same time you could call the controller using javascript from the view.
I try to open a word document with c#.
When I open the document, the page is blocked after.
Here is the code :
HttpContext.Current.Response.Write(temp);
//HttpContext.Current.Response.End();
//HttpContext.Current.Response.Flush();
//HttpContext.Current.Response.Write(sw.ToString());
//HttpContext.Current.Response.clear();
//HttpContext.Current.Response.End();
//HttpContext.Current.Response.SuppressContent = true;
//HttpContext.Current.Response.Close();
//Response.Redirect(Page.Request.Url.AbsolutePath.Substring(0, Page.Request.Url.AbsolutePath.LastIndexOf("/")) + "/PIEditor.aspx?PostID=" + Request.Params["PostID"], true);`
//HttpContext.Current.Response.End();
As you see, I tried different options but without result, the window for opening or saving the document is displayed but I can't click on any buttons the page after. It looks like it is deactivated or stopped.
you can try GemBox.Document component to export Word document from ASP.NET application, if that is what you are trying to do.
Here is a sample C# code that should go in ASPX page code behind:
// Create a new empty document.
DocumentModel document = new DocumentModel();
// Add document content.
document.Sections.Add(new Section(document, new Paragraph(document, "Hello World!")));
// Microsoft Packaging API cannot write directly to Response.OutputStream.
// Therefore we use temporary MemoryStream.
using (MemoryStream documentStream = new MemoryStream())
{
document.Save(documentStream, SaveOptions.DocxDefault);
// Stream file to browser.
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats";
Response.AddHeader("Content-Disposition", "attachment; filename=Document.docx");
documentStream.WriteTo(Response.OutputStream);
Response.End();
}
Try the below code:
//create new MemoryStream object and add PDF file’s content to outStream.
MemoryStream outStream = new MemoryStream();
//specify the duration of time before a page cached on a browser expires
Response.Expires = 0;
//specify the property to buffer the output page
Response.Buffer = true;
//erase any buffered HTML output
Response.ClearContent();
//add a new HTML header and value to the Response sent to the client
Response.AddHeader(“content-disposition”, “inline; filename=” + “output.doc”);
//specify the HTTP content type for Response as Pdf
Response.ContentType = “application/msword”;
//write specified information of current HTTP output to Byte array
Response.BinaryWrite(outStream.ToArray());
//close the output stream
outStream.Close();
//end the processing of the current page to ensure that no other HTML content is sent
Response.End();