使用iText Sharp打印PDF文件,但不适用于多个用户

本文关键字:适用于 不适用 用户 Sharp iText 打印 PDF 文件 使用 | 更新日期: 2023-09-27 18:18:53

我找不到任何其他方法从报告查看器打印报告,所以做了一些谷歌搜索,发现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";

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

使用iText Sharp打印PDF文件,但不适用于多个用户

不要生成 PDF 到文件并从中读取。 当打开文件进行写入时,它将被锁定,其他用户将被阻止访问。 这在多用户环境中是非常不安全的,除非您为每个报表实例创建一个唯一的目录或文件名(这也很糟糕,因为它将不可避免地使您的文件系统充满孤立报表,或者您必须处理临时目录权限和诸如此类有趣的东西(。 iTextSharp支持渲染到MemoryStream,该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"));

所做的只是从报表查看器(它已经是一个包含 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);

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