Подтвердить что ты не робот

Как распечатать PDF с помощью С#

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

Задача:

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

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

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

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

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


Запустите AcroRd32.exe с начальными аргументами

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

InsertPathTo..\AcroRd32.exe/t "C:\sample.pdf" "\ printerNetwork\имя_принтера"

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


Использовать предварительные настройки 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 может удовлетворить все требования.


Кто-нибудь задумался о том, чтобы получить Drawing.Image из этих PDF'ов или другого подхода, как это сделать?

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

4b9b3361

Ответ 1

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

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

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

-sPAPERSIZE = a4 -dPDFFitPage

Ответ 2

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

вы можете посмотреть Как отправить необработанные данные на принтер с помощью Visual С#.NET

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

Ответ 3

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

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

// 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. Код в С# должен выглядеть следующим образом:

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

Ответ 4

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

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

Ответ 5

Я знаю, что тег имеет 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, это не сработает.

Ответ 7

Вы можете использовать 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;

Ответ 8

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

Ответ 9

Если вам интересны коммерческие решения, которые делают именно то, что вам нужно, существует множество вариантов. Моя компания предоставляет один из этих вариантов инструментария разработчика, который называется 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);

Ответ 10

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

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

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

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