Как распечатать PDF с C#

Я пытаюсь решить эту проблему почти 2 дня. В сети есть много более или менее хороших решений, но ни одно из них не подходит мне идеально.

Задача:

  • Распечатать PDF программно
  • Сделайте это с фиксированным принтером
  • Не позволяйте пользователю делать более одного нажатия кнопки.
  • Молчи - чем больше, тем лучше
  • Сделай это на стороне клиента

Первые решения:

Сделайте это с помощью Forms.WebBrowser

Если у нас установлен Adobe Reader, есть плагин для отображения PDF-файлов в веб-браузере. С этим решением у нас есть хороший предварительный просмотр, а с помощью webbrowserControlName.Print() мы можем запустить элемент управления для печати его содержимого.

Проблема - у нас все еще есть PrintDialog.


Запустите AcroRd32.exe с аргументами запуска

Следующая команда CMD позволяет нам использовать Adobe Reader для печати нашего PDF.

InsertPathTo.. \ AcroRd32.exe / t "C: \ sample.pdf" "\ printerNetwork \ printerName"

Проблемы - нам нужен абсолютный путь к AcroRd32.exe | окно Adobe Reader открывается, и его нужно открывать до тех пор, пока задача печати не будет готова.


Используйте предустановки Windows

Process process = new Process();

process.StartInfo.FileName = pathToPdf; 
process.StartInfo.Verb = "printto";
process.StartInfo.Arguments = "\"" + printerName + "\""; 
process.Start();

process.WaitForInputIdle();
process.Kill();

Проблема - все еще появляется окно Adobe Reader, но после завершения печати оно обычно закрывается.

Решение - убедить клиента использовать Foxit Reader (не используйте последние две строки кода).


Конвертировать PDF страницы в Drawing.Image

Я понятия не имею, как сделать это с кодом, но когда я заставлю это работать, остальное - просто кусок пирога. Printing.PrintDocument может выполнить все требования.


У кого-нибудь есть идея, чтобы получить некоторые рисунки. Изображения из этих PDF-файлов или другой подход, как это сделать?

С наилучшими пожеланиями, Макс

12 ответов

Самый гибкий, простой и эффективный метод, который я смог найти, - это использование GhostScript. Он может печатать на принтерах Windows напрямую по имени принтера.

"C: \ Program Files \ gs \ gs9.07 \ bin \ gswin64c.exe" -dPrinted -dBATCH -dNOPAUSE -sDEVICE = mswinpr2 -dNoCancel -sOutputFile = "% имя принтера%" " pdfdocument.pdf "

Добавьте эти переключатели, чтобы сжать документ на странице A4.

-sPAPERSIZE = a4 -dPDFFitPage

Я перепробовал много вещей, и тот, который работал лучше всего, запускал SumatraPDF из командной строки:

// Launch SumatraPDF Reader to print
String arguments = "-print-to-default -silent \"" + fileName + "\"";
System.Diagnostics.Process.Start("SumatraPDF.exe", arguments);

Есть так много преимуществ для этого:

  1. SumatraPDF намного быстрее, чем Adobe Acrobat Reader.
  2. Пользовательский интерфейс не загружается. Это просто печатает.
  3. Вы можете использовать SumatraPDF в качестве отдельного приложения, чтобы вы могли включить его в свое приложение, чтобы вы могли использовать свой собственный год. Обратите внимание, что я не читал лицензионное соглашение; Вы, вероятно, должны проверить это сами.

Если вам нужна коммерческая библиотека, вы можете попробовать Amyuni PDF Creator. Сеть.

Печать напрямую из библиотеки:
Для открытия файла PDF и отправки его на печать напрямую вы можете использовать метод IacDocument.Print. Код в C# будет выглядеть так:

// 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);

Экспорт в изображения (затем печать при необходимости):
Вариант 1. Вы можете использовать метод IacDocument.ExportToJPeg для преобразования всех страниц в PDF в изображения JPG, которые можно распечатать или отобразить с помощью Drawing.Image

Вариант 2: Вы можете нарисовать каждую страницу в растровое изображение, используя метод IacDocument.DrawCurrentPage с методом System.Drawing.Graphics.FromImage. Код в C# должен выглядеть так:

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

Отказ от ответственности: я работаю на Amyuni Technologies

Другой подход заключается в использовании функции очереди печати в.NET для отправки предварительно отформатированных данных принтера на принтер. Но, к сожалению, вам нужно работать с Win32 спулер API

Вы можете посмотреть, как отправлять необработанные данные на принтер с помощью Visual C# .NET

Вы можете использовать этот подход только в том случае, если принтер изначально поддерживает документ PDF.

Я знаю, что тег имеет Windows Forms; однако из-за общего названия некоторые люди могут задаться вопросом, могут ли они использовать это пространство имен с WPF приложение - они могут.

Вот код:

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);
}

Теперь это пространство имен должно использоваться с WPF приложение. Это не очень хорошо с ASP.NET или же Windows Service, Не следует использовать с Windows Formsкак оно System.Drawing.Printing, У меня нет ни одной проблемы с моей печатью PDF с использованием приведенного выше кода.

Обратите внимание, что если ваш принтер не поддерживает прямую печать для файлов PDF, это не сработает.

Вы можете использовать ghostscript для преобразования PDF в графические форматы.

В следующем примере один PDF-файл преобразуется в последовательность 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();
}

Если вы предпочитаете использовать Adobe Reader, вы можете скрыть его окно:

process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

Моя компания предлагает библиотеку Docotic.Pdf, которая может отображать и печатать PDF-документы . Статья по ссылке содержит подробную информацию по следующим темам:

  • печать PDF-файлов напрямую в Windows Forms или приложении WPF
  • печать PDF-файлов через промежуточное изображение
  • рендеринг PDF-файлов на графике

Также есть ссылки на образец кода.

Я работаю в компании, поэтому ознакомьтесь со статьей и попробуйте предложенные решения самостоятельно.

Я нашел немного другую версию вашего кода, которая использует глагол printto. Я не пробовал, но, возможно, это поможет вам:

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

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

Если вы заинтересованы в коммерческих решениях, которые делают именно то, что вам нужно, то есть немало вариантов. Моя компания предоставляет один из этих вариантов в наборе инструментов разработчика под названием Debenu Quick PDF Library.

Вот пример кода (основными функциями являются PrintOptions и 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);

По состоянию на July 2018, до сих пор нет ответа для ОП. Не существует бесплатного способа 1) молча распечатать ваш PDF для 2) проекта с закрытым исходным кодом.

1) Вы наверняка можете использовать процесс, например, Adobe Acrobat или Foxit Reader.

2) Бесплатные решения имеют GPL (стандартную публичную лицензию GNU). Это означает, что вы должны открыть свой исходный код, если вы предоставляете программное обеспечение, даже бесплатно, кому-либо за пределами вашей компании.

Как говорится в ОП, если вы можете получить PDF для Drawing.Image, вы можете распечатать его с помощью методов.NET. К сожалению, программное обеспечение для этого также требует оплаты или GPL.

Как насчет использования PrintDocument учебный класс?

http://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument.aspx

Вам просто нужно передать имя файла, который вы хотите распечатать (на примере).

НТН

Другие вопросы по тегам