J'essaie de résoudre ce problème depuis près de 2 jours. Il y a beaucoup plus ou moins de bonnes solutions sur le net, mais aucune ne correspond parfaitement à ma tâche.
Faites-le avec un Forms.WebBrowser
Si Adobe Reader est installé, il existe un plug-in pour afficher les fichiers PDF dans le navigateur Web. Avec cette solution, nous avons un aperçu de Nice et avec webbrowserControlName.Print (), nous pouvons déclencher le contrôle pour imprimer son contenu.
Problème - nous avons toujours un PrintDialog.
Démarrez AcroRd32.exe avec les arguments de démarrage
La commande CMD suivante nous permet d’utiliser Adobe Reader pour imprimer notre fichier PDF.
InsertPathTo ..\AcroRd32.exe/t "C:\échantillon.pdf" "\ printerNetwork\printerName"
Problems - nous avons besoin du chemin absolu vers AcroRd32.exe | une fenêtre Adobe Reader s'ouvre et doit être ouverte jusqu'à ce que la tâche d'impression soit prête.
Utiliser les préréglages Windows
Process process = new Process();
process.StartInfo.FileName = pathToPdf;
process.StartInfo.Verb = "printto";
process.StartInfo.Arguments = "\"" + printerName + "\"";
process.Start();
process.WaitForInputIdle();
process.Kill();
Problème - une fenêtre Adobe Reader s’ouvre toujours, mais une fois l’impression terminée, elle se ferme habituellement.
Solution - convaincre le client d’utiliser Foxit Reader (n’utilisez pas les deux dernières lignes de code).
Convertissez PDF pages en Drawing.Image
Je ne sais pas comment faire avec du code, mais quand je réussis, le reste n'est plus qu'un morceau de gâteau. Printing.PrintDocument peut répondre à toutes les demandes.
Cordialement, Max
La méthode la plus flexible, la plus simple et la plus performante que j'ai pu trouver était d'utiliser GhostScript. Il peut imprimer directement sur les imprimantes Windows par nom d’imprimante.
"C:\Program Files\gs\gs9.07\bin\gswin64c.exe" -d Imprimé -dBATCH -dNOPAUSE -sDEVICE = mswinpr2 -dNoCancel -sOutputFile = "% printer% nom de l'imprimante " " pdfdocument. pdf "
Ajoutez ces commutateurs pour réduire le document à une page A4.
-sPAPERSIZE = a4 -dPDFFitPage
Si une bibliothèque commerciale est une option, vous pouvez essayer avec Amyuni PDF Creator. Net.
Imprimer directement avec la bibliothèque:
Pour ouvrir un fichier PDF et l'envoyer pour l'imprimer directement, vous pouvez utiliser la méthode IacDocument.Print . Le code en C # ressemblera à ceci:
// Open PDF document from file<br>
FileStream file1 = new FileStream ("test.pdf", FileMode.Open, FileAccess.Read);
IacDocument doc1 = new IacDocument (null);
doc1.Open (file1, "" );
// print document to a specified printer with no Prompt
doc1.Print ("My Laser Printer", false);
Exporter vers des images (puis imprimer si nécessaire):
Choix 1: vous pouvez utiliser la méthode IacDocument.ExportToJPeg pour convertir toutes les pages d’un PDF en images JPG que vous pouvez imprimer ou afficher à l’aide de Drawing.Image
Choix 2: vous pouvez dessiner chaque page dans un bitmap en utilisant la méthode IacDocument.DrawCurrentPage avec la méthode System.Drawing.Graphics.FromImage . Le code en C # devrait ressembler à ceci:
FileStream myFile = new FileStream ("test.pdf", FileMode.Open, FileAccess.Read);
IacDocument doc = new IacDocument(null);
doc.Open(myFile);
doc.CurrentPage = 1;
Image img = new Bitmap(100,100);
Graphics gph = Graphics.FromImage(img);
IntPtr hdc = gph.GetHDC();
doc.DrawCurrentPage(hdc, false);
gph.ReleaseHdc( hdc );
_ {Disclaimer: Je travaille pour Amyuni Technologies} _
Une autre approche consiste à utiliser la fonction spouleur dans .NET pour envoyer les données d’imprimante pré-formatées à une imprimante. Mais malheureusement, vous devez travailler avec l'API Win32 Spooler.
vous pouvez regarder Comment envoyer des données brutes à une imprimante à l'aide de Visual C # .NET
vous ne pouvez utiliser cette approche que lorsque l'imprimante prend en charge le document PDF de manière native.
J'ai trouvé une version légèrement différente de votre code qui utilise le verbe printto. Je ne l'ai pas essayé, mais peut-être que ça vous aide:
Je sais que la balise a Windows Forms
; Cependant, en raison du titre général, certaines personnes pourraient se demander si elles peuvent utiliser cet espace de noms avec une application WPF
- elles le peuvent.
Voici le code:
var file = File.ReadAllBytes(pdfFilePath);
var printQueue = LocalPrintServer.GetDefaultPrintQueue();
using (var job = printQueue.AddJob())
using (var stream = job.JobStream)
{
stream.Write(file, 0, file.Length);
}
Maintenant, cet espace de noms doit être utilisé avec une application WPF
. Cela ne fonctionne pas bien avec ASP.NET
ou Windows Service
. Il ne devrait pas être utilisé avec Windows Forms
, car il a System.Drawing.Printing
. Je n'ai pas un seul problème avec mon PDF impression utilisant le code ci-dessus.
Notez que si votre imprimante ne prend pas en charge l'impression directe pour les fichiers PDF, cela ne fonctionnera pas.
Vous pouvez utiliser ghostscript pour convertir PDF en formats d'image.
L'exemple suivant convertit un seul PDF en une séquence de fichiers PNG:
private static void ExecuteGhostscript(string input, string tempDirectory)
{
// %d will be replaced by ghostscript with a number for each page
string filename = Path.GetFileNameWithoutExtension(input) + "-%d.png";
string output = Path.Combine(tempDirectory, filename);
Process ghostscript = new Process();
ghostscript.StartInfo.FileName = _pathToGhostscript;
ghostscript.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
ghostscript.StartInfo.Arguments = string.Format(
"-dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r300 -sOutputFile=\"{0}\" \"{1}\"", output, input);
ghostscript.Start();
ghostscript.WaitForExit();
}
Si vous préférez utiliser Adobe Reader à la place, vous pouvez masquer sa fenêtre:
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
À la date de July 2018
, il n’ya toujours pas de réponse pour le PO. Il n’existe aucun moyen gratuit 1) d’imprimer en silence votre pdf pour un projet 2) à source fermée.
1) Vous pouvez très certainement utiliser un processus, à savoir Adobe Acrobat ou Foxit Reader
2) Les solutions gratuites ont une licence GPL (licence publique générale de GNU). Cela signifie que vous devez ouvrir votre code source si vous donnez le logiciel, même gratuitement, à une personne extérieure à votre entreprise.
Comme le dit l'OP, si vous pouvez obtenir un PDF dans Drawing.Image, vous pouvez l'imprimer avec les méthodes .NET. Malheureusement, le logiciel nécessite également un paiement ou une licence GPL.
J'ai essayé beaucoup de choses et celle qui a le mieux fonctionné pour moi était de lancer un SumatraPDF depuis la ligne de commande:
// Launch SumatraPDF Reader to print
String arguments = "-print-to-default -silent \"" + fileName + "\"";
System.Diagnostics.Process.Start("SumatraPDF.exe", arguments);
Il y a tellement d'avantages à cela:
Si vous êtes intéressé par des solutions commerciales qui répondent exactement à vos besoins, vous avez plusieurs options. Ma société propose l’une de ces options dans une boîte à outils de développement appelée Bibliothèque Debenu Quick PDF .
Voici un exemple de code (les fonctions clés sont PrintOptions et PrintDocument ):
/* Print a document */
// Load a local sample file from the input folder
DPL.LoadFromFile("Test.pdf", "");
// Configure print options
iPrintOptions = DPL.PrintOptions(0, 0, "Printing Sample")
// Print the current document to the default
// printing using the options as configured above.
// You can also specify the specific printer.
DPL.PrintDocument(DPL.GetDefaultPrinterName(), 1, 1, iPrintOptions);
Qu'en est-il de l'utilisation de la classe PrintDocument
?
http://msdn.Microsoft.com/en-us/library/system.drawing.printing.printdocument.aspx
Il vous suffit de transmettre le nom du fichier que vous souhaitez imprimer (basé sur l'exemple).
HTH
Process proc = new Process();
proc.StartInfo.FileName = @"C:\Program Files\Adobe\Acrobat 7.0\Reader\AcroRd32.exe";
proc.StartInfo.Arguments = @"/p /h C:\Documents and Settings\brendal\Desktop\Test.pdf";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
for (int i = 0; i < 5; i++)
{
if (!proc.HasExited)
{
proc.Refresh();
Thread.Sleep(2000);
}
else
break;
}
if (!proc.HasExited)
{
proc.CloseMainWindow();
}