Как я могу отправить файл документа на принтер и распечатать его? - PullRequest
60 голосов
/ 24 мая 2011

Вот основная посылка:

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

string filePath = "filepathisalreadysethere";
SendToPrinter(filePath); //Something like this?

Он будет делать этот процесс много раз. Для каждого ученика в классе он должен распечатать небольшую табель успеваемости. Поэтому я создаю PDF для каждого учащегося и хотел бы автоматизировать процесс печати вместо того, чтобы пользователь генерировал PDF, печатал, генерировал PDF, печатал, генерировал PDF, печатал.

Есть предложения, как к этому подойти? Я работаю на Windows XP с Windows Forms .NET 4.

Я нашел этот StackOverflow вопрос, где принятый ответ предполагает:

Как только вы создали свои файлы, вы можете распечатать их через командную строку (вы можно с помощью класса Command, найденного в пространство имен System.Diagnostics для что)

Как бы мне этого добиться?

Ответы [ 11 ]

60 голосов
/ 24 мая 2011

Вы можете указать Acrobat Reader распечатать файл, используя (как уже упоминалось здесь) глагол «печать». После этого вам также необходимо программно закрыть Acrobat Reader:

private void SendToPrinter()
{
   ProcessStartInfo info = new ProcessStartInfo();
   info.Verb = "print";
   info.FileName = @"c:\output.pdf";
   info.CreateNoWindow = true;
   info.WindowStyle = ProcessWindowStyle.Hidden;

   Process p = new Process();
   p.StartInfo = info;
   p.Start();

   p.WaitForInputIdle();
   System.Threading.Thread.Sleep(3000);
   if (false == p.CloseMainWindow())
      p.Kill();
}

При этом откроется Acrobat Reader и сообщит, что нужно отправить PDF на принтер по умолчанию, а затем через три секунды завершит работу Acrobat.

Если вы хотите поставлять другие продукты вместе с вашим приложением, вы можете использовать GhostScript (бесплатный) или принтер PDF для командной строки, например http://www.commandlinepdf.com/ (коммерческий).

Примечание: образец кода открывает PDF-файл в текущем приложении, зарегистрированном для печати PDF-файлов , которое является программой Adobe Acrobat Reader на машинах большинства людей. Тем не менее, возможно, что они используют другое средство просмотра PDF, например Foxit (http://www.foxitsoftware.com/pdf/reader/).. Однако пример кода все равно должен работать.

50 голосов
/ 19 января 2017

Добавление нового ответа на этот вопрос, поскольку вопрос печати PDF в .net существует давно, и большинство ответов предшествует библиотеке Google Pdfium, которая теперь имеет оболочку .net. Что касается меня, я сам исследовал эту проблему и все время терял сознание, пытаясь найти хакерские решения, такие как порождение Acrobat или других программ для чтения PDF-файлов, или наткнуться на коммерческие библиотеки, которые дороги и не очень совместимы с условиями лицензии. Но библиотека Google Pdfium и оболочка PdfiumViewer .net с открытым исходным кодом, поэтому являются отличным решением для многих разработчиков, включая меня. PdfiumViewer лицензируется под лицензией Apache 2.0.

Вы можете получить пакет NuGet здесь:

https://www.nuget.org/packages/PdfiumViewer/

и вы можете найти исходный код здесь:

https://github.com/pvginkel/PdfiumViewer

Вот простой код, который будет молча печатать любое количество копий PDF-файла из его имени. Вы также можете загружать PDF-файлы из потока (как мы обычно это делаем), и вы можете легко понять это, взглянув на код или примеры. Существует также вид файла WinForm PDF, так что вы также можете визуализировать файлы PDF в виде или сделать предварительный просмотр на них. Для нас мне просто нужен был способ распечатать файл PDF на определенном принтере по запросу.

public bool PrintPDF(
    string printer,
    string paperName,
    string filename,
    int copies)
{
    try {
        // Create the printer settings for our printer
        var printerSettings = new PrinterSettings {
            PrinterName = printer,
            Copies = (short)copies,
        };

        // Create our page settings for the paper size selected
        var pageSettings = new PageSettings(printerSettings) {
            Margins = new Margins(0, 0, 0, 0),
        };
        foreach (PaperSize paperSize in printerSettings.PaperSizes) {
            if (paperSize.PaperName == paperName) {
                pageSettings.PaperSize = paperSize;
                break;
            }
        }

        // Now print the PDF document
        using (var document = PdfDocument.Load(filename)) {
            using (var printDocument = document.CreatePrintDocument()) {
                printDocument.PrinterSettings = printerSettings;
                printDocument.DefaultPageSettings = pageSettings;
                printDocument.PrintController = new StandardPrintController();
                printDocument.Print();
            }
        }
        return true;
    } catch {
        return false;
    }
}
26 голосов
/ 11 декабря 2014

Я знаю, что тег говорит Windows Forms ... но, если кто-то заинтересован в WPF методе применения, System.Printing работает как шарм.

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

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

Однако я должен отметить, что если ваш принтер не поддерживает Direct Print для формата PDF, вам не повезло с этим методом.

9 голосов
/ 12 сентября 2014

Это слегка модифицированное решение.Процесс будет убит, когда он простаивал не менее 1 секунды.Возможно, вам следует добавить время X секунд и вызвать функцию из отдельного потока.

private void SendToPrinter()
{
  ProcessStartInfo info = new ProcessStartInfo();
  info.Verb = "print";
  info.FileName = @"c:\output.pdf";
  info.CreateNoWindow = true;
  info.WindowStyle = ProcessWindowStyle.Hidden;

  Process p = new Process();
  p.StartInfo = info;
  p.Start();

  long ticks = -1;
  while (ticks != p.TotalProcessorTime.Ticks)
  {
    ticks = p.TotalProcessorTime.Ticks;
    Thread.Sleep(1000);
  }

  if (false == p.CloseMainWindow())
    p.Kill();
}
7 голосов
/ 26 апреля 2018

Следующий фрагмент кода представляет собой адаптацию кода Кендалла Беннетта для печати PDF-файлов с использованием библиотеки PdfiumViewer. Основное отличие состоит в том, что используется поток, а не файл.

public bool PrintPDF(
    string printer,
    string paperName,
    int copies, Stream stream)
        {
            try
            {
                // Create the printer settings for our printer
                var printerSettings = new PrinterSettings
                {
                    PrinterName = printer,
                    Copies = (short)copies,
                };

            // Create our page settings for the paper size selected
            var pageSettings = new PageSettings(printerSettings)
            {
                Margins = new Margins(0, 0, 0, 0),
            };
            foreach (PaperSize paperSize in printerSettings.PaperSizes)
            {
                if (paperSize.PaperName == paperName)
                {
                    pageSettings.PaperSize = paperSize;
                    break;
                }
            }

            // Now print the PDF document
            using (var document = PdfiumViewer.PdfDocument.Load(stream))
            {
                using (var printDocument = document.CreatePrintDocument())
                {
                    printDocument.PrinterSettings = printerSettings;
                    printDocument.DefaultPageSettings = pageSettings;
                    printDocument.PrintController = new StandardPrintController();
                    printDocument.Print();
                }
            }
            return true;
        }
        catch (System.Exception e)
        {
            return false;
        }
    }

В моем случае я генерирую PDF-файл, используя библиотеку PdfSharp, а затем сохраняю документ в Stream следующим образом:

        PdfDocument pdf = PdfGenerator.GeneratePdf(printRequest.html, PageSize.A4);
        pdf.AddPage();

        MemoryStream stream = new MemoryStream();
        pdf.Save(stream);
        MemoryStream stream2 = new MemoryStream(stream.ToArray());

Одна вещь, на которую я хотел бы обратить внимание, которая может быть полезна другим разработчикам, - это то, что мне пришлось установить 32-битную версию ddf pdfuim native, чтобы печать работала, даже если я работаю в 64-битной Windows 10. Я установил следующие два пакета NuGet с помощью диспетчера пакетов NuGet в Visual Studio:

  • PdfiumViewer
  • PdfiumViewer.Native.x86.v8-РФ
3 голосов
/ 24 мая 2011

System.Diagnostics.Process.Start может использоваться для печати документа.Установите для UseShellExecute значение True, а для глагола - «печать».

2 голосов
/ 01 июня 2016

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

public void PrintAllFiles()
{
    System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();
    info.Verb = "print";
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    //Load Files in Selected Folder
    string[] allFiles = System.IO.Directory.GetFiles(Directory);
    foreach (string file in allFiles)
    {
        info.FileName = @file;
        info.CreateNoWindow = true;
        info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
         p.StartInfo = info;
        p.Start();
    }
    //p.Kill(); Can Create A Kill Statement Here... but I found I don't need one
    MessageBox.Show("Print Complete");
}

По сути, он циклически просматривает каждый файл в заданной переменной каталога Directory -> для меня это было @ "C: \ Users \ Owner \ Documents \ SalesVaultTesting \" и распечатывает эти файлы на принтере по умолчанию .

2 голосов
/ 21 октября 2015

это поздний ответ, но вы также можете использовать метод File.Copy в пространстве имен System.IO top, чтобы отправить файл на принтер:

System.IO.File.Copy(filename, printerName);

Это прекрасно работает

2 голосов
/ 26 декабря 2014

Простой способ:

var pi=new ProcessStartInfo("C:\file.docx");
pi.UseShellExecute = true;
pi.Verb = "print";
var process =  System.Diagnostics.Process.Start(pi);
2 голосов
/ 24 мая 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...