2015-10-21 43 views
0

我找不到任何其他方式来从报告查看器打印报告,所以做了一些Google搜索,发现了itext sharp,所以首先生成报告,然后在源文件,然后我点击打印按钮,它打印刚创建的pdf,通过在客户端机器上打开PDF的打印选项,但我遇到的问题是多个用户生成报告并打印他们得到的pdf一个错误说资源已被使用,请问我是否有解决这个问题的办法或者我可以在客户机上打印报告的其他方式?使用itext sharp来打印pdf文件,但不适用于多个用户

代码,我用它来打印

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"; 

有任何替代和使用外部按钮可打印从报表查看器报告更快的方法?

回答

4

不生成PDF并从文件读取。当一个文件被打开写入时,它将被锁定,其他用户将被禁止访问。这在多用户环境中是非常不安全的,除非您为每个报表实例创建一个唯一的目录或文件名(这也是不好的,因为它不可避免地让文件系统充满孤立的报表,或者必须处理临时目录权限,有趣的东西)。 iTextSharp支持渲染到可用于生成字节数组的MemoryStream,而该数组又可以传输到浏览器。使用一个MemoryStream从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的

此代码:

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")); 

所有这一切都做的是从的ReportViewer的输出(这是已经包含PDF的字节数组),将其写入文件,然后使用iTextSharp打开文件。从我所看到的,iTextSharp的PDFReader对象也可以使用一个字节数组初始化,所以为什么不跳过所有的代码,做:

byte[] bytes = ReportViewer1.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamids, out warnings); 

PdfReader reader = new PdfReader(bytes); 

然后就是离开你的代码相同的其他人呢?

+0

但我如何设置内存流来读取reportviewer的字节?这是否意味着他们的客户需要安装杂技演员?如果客户不使用pdf,并且我可以将内容从存储器传输到网络表单上,那将会很好。 – ExpertWannaBe

+0

增加了额外的代码示例。 – DVK