web-dev-qa-db-fra.com

Comment imprimer un PDF avec C #

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.

Tâche:

  • Imprimer un PDF par programme
  • Faites-le avec une imprimante fixe
  • Ne laissez pas l’utilisateur faire plus d’un Button_Click
  • Faites-le en silence - plus il y en a, mieux c'est
  • Fais le coté client

Premières solutions:

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. 


Quelqu'un a une idée pour obtenir Drawing.Image de ces PDF ou une autre approche, comment le faire?

Cordialement, Max

20
Mx.

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

5

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

3
yms

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.

3
Turbot

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:

http://vbcity.com/forums/t/149141.aspx

1
Hinek

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.

1
B.K.

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;
1
pescolino

À 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.

0
John Doe

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:

  1. SumatraPDF est beaucoup plus rapide que Adobe Acrobat Reader.
  2. L'interface utilisateur ne charge pas. Il imprime juste.
  3. Vous pouvez utiliser SumatraPDF en tant qu'application autonome pour pouvoir l'inclure à votre application afin que vous puissiez utiliser votre propre pa. Notez que je n'ai pas lu le contrat de licence. vous devriez probablement le vérifier vous-même.
0
Ian

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

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

0
Gavin
        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();
        }
0
Roshana