Reputation: 117
I could not find any other way to print an report from report viewer so did some googling and found itext sharp so first i generate the report then an pdf is created in the source file then i click the print button it prints the pdf that was just created by bringing up the print options of the pdf on the client machine, but the issue i am having is when multiple users generate the report and print the pdf they get an error saying that resource is in use already, can you please let me know if there is a workaround for this issue or any other way in which i can print reports on the client machine??
Code i use to print
using iTextSharp.text.pdf;
using iTextSharp.text;
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string extension;
byte[] bytes = ReportViewer1.LocalReport.Render("PDF", null, out mimeType,
out encoding, out extension, out streamids, out warnings);
FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("output.pdf"),
FileMode.Create);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
//Open existing PDF
Document document = new Document(PageSize.LETTER);
PdfReader reader = new PdfReader(HttpContext.Current.Server.MapPath("output.pdf"));
//Getting a instance of new PDF writer
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(
HttpContext.Current.Server.MapPath("Print.pdf"), FileMode.Create));
document.Open();
PdfContentByte cb = writer.DirectContent;
int i = 0;
int p = 0;
int n = reader.NumberOfPages;
Rectangle psize = reader.GetPageSize(1);
float width = psize.Width;
float height = psize.Height;
//Add Page to new document
while (i < n)
{
document.NewPage();
p++;
i++;
PdfImportedPage page1 = writer.GetImportedPage(reader, i);
cb.AddTemplate(page1, 0, 0);
}
//Attach javascript to the document
PdfAction jAction = PdfAction.JavaScript("this.print(true);\r", writer);
writer.AddJavaScript(jAction);
document.Close();
//Attach pdf to the iframe
frmPrint.Attributes["src"] = "Print.pdf";
is there any alternative and faster way to print report from report viewer using an external button?
Upvotes: 0
Views: 4337
Reputation: 2792
Don't generate the PDF to and read from a file. When a file is opened for writing, it will be locked and other users will be prevented access. That is highly unsafe in a multiple user environment unless you create a unique directory or filename for each report instance (which is bad too, because it will inevitably leave your file system full of orphaned reports or you have to deal with temp directory permissions and that kind of fun stuff). iTextSharp supports rendering to a MemoryStream which could be used to produce a byte array, which in turn could be streamed to the browser.
Example of using a memorystream from C# 3.0 Save itextsharp pdf to database using MemoryStream
function byte[] CreatePdf(){
byte[] result;
using (MemoryStream ms = new MemoryStream())
{
Document pDoc = new Document(PageSize.A4, 0, 0, 0, 0);
PdfWriter writer = PdfWriter.GetInstance(pDoc, ms);
pDoc.Open();
//here you can create your own pdf.
pDoc.Close();
result = ms.GetBuffer();
}
return result;
}
EDIT
This code:
byte[] bytes = ReportViewer1.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamids, out warnings);
FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("output.pdf"),
FileMode.Create);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
//Open existing PDF
Document document = new Document(PageSize.LETTER);
PdfReader reader = new PdfReader(HttpContext.Current.Server.MapPath("output.pdf"));
All that is doing is taking the output from the reportviewer (which is already a byte array containing the PDF), writing it to a file, and then opening the file using iTextSharp. From what I can see, the iTextSharp PDFReader object can also be instantiated using a byte array, so why not just skip all that code and do:
byte[] bytes = ReportViewer1.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamids, out warnings);
PdfReader reader = new PdfReader(bytes);
And then just leave the rest of your code the same?
Upvotes: 4