0

我找不到从报告查看器打印报告的任何其他方法,所以做了一些谷歌搜索,发现 itext 清晰,所以首先我生成报告,然后在源文件中创建一个 pdf,然后我点击打印按钮,它打印了刚刚的 pdf通过在客户端机器上调出 pdf 的打印选项创建,但我遇到的问题是当多个用户生成报告并打印 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

1 回答 1

4

不要将 PDF 生成到文件并从文件中读取。当打开一个文件进行写入时,它将被锁定,其他用户将被禁止访问。这在多用户环境中是非常不安全的,除非您为每个报告实例创建一个唯一的目录或文件名(这也很糟糕,因为它不可避免地会使您的文件系统充满孤立的报告,或者您必须处理临时目录权限并且一种有趣的东西)。iTextSharp 支持渲染到可用于生成字节数组的 MemoryStream,然后可以将其流式传输到浏览器。

使用C# 3.0 中的内存流的示例 使用 MemoryStream 将 itextsharp pdf 保存到数据库

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

编辑

这段代码:

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

然后将其余代码保持不变?

于 2015-10-21T20:28:08.953 回答