2015-10-21 1 views
0

Je n'ai pas trouvé d'autre moyen d'imprimer un rapport à partir de la visionneuse de rapports, donc j'ai fait googler et trouvé itext si je génère le rapport puis un pdf est créé dans le fichier source puis je clique sur le bouton d'impression, il imprime le pdf qui vient d'être créé en soulevant les options d'impression du pdf sur la machine client, mais le problème que je rencontre est lorsque plusieurs utilisateurs génèrent le rapport et imprimer le pdf qu'ils obtiennent une erreur indiquant que cette ressource est déjà utilisée, pouvez-vous me faire savoir s'il existe une solution de contournement pour ce problème ou toute autre méthode permettant d'imprimer des rapports sur la machine cliente?en utilisant itext pointu pour imprimer des fichiers PDF mais ne fonctionnant pas pour plusieurs utilisateurs

code i utiliser pour imprimer

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

est-il une alternative et plus rapide pour imprimer un rapport de visionneuse de rapport à l'aide d'un bouton externe?

Répondre

4

Ne pas générer le fichier PDF et lire à partir d'un fichier. Quand un fichier est ouvert pour l'écriture, il sera verrouillé et les autres utilisateurs seront empêchés d'accéder. Cela est très dangereux dans un environnement multi-utilisateur, sauf si vous créez un répertoire ou un nom de fichier unique pour chaque instance de rapport (ce qui est également dangereux car il laissera inévitablement votre système de fichiers plein de rapports orphelins ou vous devrez gérer les permissions du répertoire temporaire. genre de choses amusantes). iTextSharp prend en charge le rendu vers un MemoryStream qui pourrait être utilisé pour produire un tableau d'octets, qui à son tour pourrait être transmis au navigateur.

Exemple d'utilisation d'un MemoryStream de 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

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

Tout ce qui est en train de faire est de prendre la sortie de la ReportViewer (qui est déjà un tableau d'octets contenant le PDF), en l'écrivant dans un fichier, puis en ouvrant le fichier en utilisant iTextSharp. D'après ce que je peux voir, l'objet iTextSharp PDFReader peut également être instancié à l'aide d'un tableau d'octets, alors pourquoi ne pas sauter juste tout ce code et faire:

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

PdfReader reader = new PdfReader(bytes); 

Et puis il suffit de laisser le reste de votre code même?

+0

mais comment puis-je définir le flux de mémoire pour lire les octets du ReportViewer? et cela signifie-t-il que les clients doivent avoir un acrobat installé? ce serait génial si les clients n'utilisaient pas pdf et si je peux simplement diffuser le contenu de la mémoire sur un formulaire Web – ExpertWannaBe

+0

Ajout d'un exemple de code supplémentaire. – DVK