Использование itext sharp для печати PDF-файлов, но не работает для нескольких пользователей
Я не мог найти какой-либо другой способ распечатать отчет из средства просмотра отчетов, поэтому сделал поиск в гугле и нашел четкий текст, поэтому сначала я генерирую отчет, затем создается файл 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";
Есть ли альтернативный и более быстрый способ печати отчета из средства просмотра отчетов с помощью внешней кнопки?
1 ответ
Не создавайте PDF и не читайте из файла. Когда файл открыт для записи, он будет заблокирован, и другим пользователям будет закрыт доступ. Это очень небезопасно в многопользовательской среде, если вы не создадите уникальный каталог или имя файла для каждого экземпляра отчета (что тоже плохо, потому что это неизбежно приведет к тому, что ваша файловая система будет заполнена потерянными отчетами или вам придется иметь дело с разрешениями временного каталога и забавные вещи). iTextSharp поддерживает рендеринг в MemoryStream, который можно использовать для создания байтового массива, который, в свою очередь, может передаваться в браузер.
Пример использования потока памяти из C# 3.0 Сохранить файл itextsharp в базу данных с помощью 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;
}
РЕДАКТИРОВАТЬ
Этот код:
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);
А потом просто оставить остальную часть своего кода таким же?