Вопрос

Сейчас я работаю над проектом, который предполагает получение сообщения из другого приложения, форматирование содержимого этого сообщения и отправку его на принтер.Предпочтительной технологией является служба Windows C#.Я полагаю, что результат можно назвать отчетом, но механизм отчетов не обязателен.Подойдет простой шаблонизатор, такой как StringTemplate, или даже XSLT, выводящий HTML.Проблема, с которой я столкнулся, заключается в том, чтобы найти бесплатный способ распечатать такой вывод из службы.С тех пор кажется Чтобы это сработало, я работаю над прототипом с использованием Microsoft RDLC, заполняю локальный отчет, а затем отображаю его как изображение в потоке памяти, который затем распечатаю.Проблемы с этим:

  • Многостраничная печать станет большой головной болью.
  • Все равно придется использовать PrintDocument для печати потока памяти, который не поддерживается в службе Windows (хотя это может работать - еще не зашел так далеко с прототипом)
  • Если поступающие данные изменяются, мне придется изменить набор данных и класс, в который десериализуются данные.плохо плохо плохо.

Кому-нибудь приходилось делать что-то подобное удаленно?Любой совет?Я уже задавал вопрос о печати HTML без ввода данных пользователем и, потратив на это около 3 дней, пришел к выводу, что это невозможно сделать, по крайней мере, с помощью любого свободно доступного инструмента.

Вся помощь приветствуется.

РЕДАКТИРОВАТЬ:Мы используем версию 2.0 платформы .NET.

Это было полезно?

Решение

Поверьте мне, вы потратите больше денег на поиск/разработку решения для этой проблемы, чем на покупку стороннего компонента.Не изобретайте велосипед и не выбирайте платное решение.

Печать — сложная проблема, и мне бы хотелось увидеть тот день, когда для этого будет добавлена ​​лучшая поддержка платформы.

Другие советы

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

Недавно я столкнулся с этой проблемой и после нескольких неудачных проб и экспериментов наконец пришел к двум жизнеспособным решениям:

  • Напишите свою собственную DLL для печати, используя Win32 API (например, на C/C++), затем используйте ее из своей службы с P/Invoke (работает нормально)
  • Напишите собственный компонент COM+ для печати, а затем используйте его из своей службы.Недавно я успешно выбрал это решение (но это был сторонний компонент COM+, а не написанный самостоятельно). Оно тоже работает абсолютно нормально.

Я сделал это.Это боль в заднице.Проблема в том, что для печати требуется наличие механизма GDI, а это обычно означает, что у вас должен быть рабочий стол, который загружается только при входе в систему.Если вы пытаетесь сделать это из службы на сервере, то обычно вы не вошли в систему.

Итак, во-первых, вы можете работать не как обычный пользователь службы, а как настоящий пользователь, имеющий права интерактивного входа в систему.Затем вам нужно настроить записи реестра службы (сейчас я забыл, как это сделать, мне придется найти код, который я могу сделать сегодня вечером, если вам действительно интересно).Наконец, вам нужно молиться.

Ваша самая большая долгосрочная головная боль будет связана с драйверами печати.Если вы работаете как служба без вошедшего в систему пользователя, некоторые драйверы печати любят время от времени отображать всплывающие диалоговые окна.Что произойдет, если в вашем принтере закончится тонер?Или закончилась бумага?Драйвер может открыть диалоговое окно, которое никогда не будет видно, и задержать очередь принтера, потому что никто не вошел в систему!

Распечатывать из сервиса — плохая идея.Сетевые принтеры подключаются «для каждого пользователя».Вы можете пометить службу для запуска от имени конкретного пользователя, но я бы посчитал это плохой практикой безопасности.Возможно, вы сможете подключиться к локальному принтеру, но я бы все равно колебался, прежде чем идти по этому пути.

Лучший вариант — оставить данные в сервисе, а пользовательское приложение выполнит печать, запрашивая данные у сервиса.Или общее место хранения данных, например база данных.

Если вам нужно, чтобы данные печатались через регулярные промежутки времени, настройте событие задачи через планировщик задач.Запуск процесса из службы потребует знания имени пользователя и пароля, что опять же является плохой практикой безопасности.

Что касается самой печати, проще всего будет воспользоваться сторонним инструментом для формирования отчета.

Чтобы ответить на ваш первый вопрос, это может быть довольно просто, в зависимости от данных.У нас есть множество сервисных приложений, которые делают именно то, что вы просите.Обычно мы анализируем входящий файл и оборачиваем его собственным Postscript или PCL.Если ваш макет довольно прост, то есть несколько очень простых кодов PCL, в которые вы можете его обернуть, чтобы обеспечить желаемый макет шрифта/печати (я был бы более чем рад дать вам некоторые рекомендации здесь в автономном режиме).

Если у вас есть готовый к печати файл, вы можете отправить его на общий UNC-принтер, непосредственно на локально установленный принтер или даже на IP-адрес устройства (данные типа RAW или LPR).

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

Другой вариант — запустить Призрачный скрипт который должен быть бесплатным для ваших нужд (проверьте лицензию, так как у них есть несколько разных версий, некоторые GNU, некоторые GPL и т. д.), и либо используйте встроенную функцию печати, либо просто преобразуйте в Postscript и отправьте на устройство.Я много раз использовал Ghostscript в сервисных приложениях, но не большой его поклонник, так как для преобразования вам, по сути, придется раскошелиться и запустить приложение командной строки.При этом это стабильное приложение, которое имеет тенденцию изящно выходить из строя.

Возможно, это не то, что вы ищете, но если бы мне нужно было сделать это быстро и грязно, я бы:

  1. Создайте отдельное приложение WPF (чтобы я мог использовать встроенную обработку документов)
  2. Предоставьте службе возможность взаимодействовать с рабочим столом (обратите внимание, что вам на самом деле не нужно ничего показывать на рабочем столе или входить в систему, чтобы это работало)
  3. Попросите службу запустить приложение и передать ему данные для печати.

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

Для более подробного (также бесплатного) решения лучше всего вручную отформатировать документ самостоятельно (используя GDI+ для создания макета за вас).Это утомительно, чревато ошибками, отнимает много времени и тратит много бумаги во время разработки, но также дает вам максимальный контроль над тем, что поступает на принтер.

Если вы можете выводить в пост-скрипт, некоторые принтеры будут печатать все, что передается по FTP в определенный каталог на них.

Мы использовали это, чтобы обойти кредиты на печать, которые наш университет выставил нам, но если ваша служба выводит данные на PS, вы можете просто передать PS-файл на принтер.

Мы используем DevExpress XtraReports распечатать из сервиса без проблем.Их модель отчета аналогична модели Windows Forms, поэтому вы можете динамически вставлять текстовые элементы, а затем запускать команду печати.

Я думаю, мы собираемся пойти по пути третьей стороны.Мне нравится XSL -> HTML -> PDF -> поток печати...Winnovative's HTML в PDF выглядит хорошо для первой части, но я сталкиваюсь с проблемой в поисках хорошего решения для печати PDF...какие-либо предложения?В идеале лицензия должна предоставляться для разработчиков, а не для развернутой среды выполнения.

Отвечая на ваш вопрос о печати PDF, я не нашел элегантного решения.Я «подключался» к Adobe, что было ненадежно и требовало, чтобы пользователь постоянно входил в систему.Чтобы решить эту конкретную проблему, я попросил, чтобы файлы, которые мы обрабатываем (счета-фактуры), были отформатированы как многостраничные файлы Tiff, которые можно было бы разделить и распечатать с использованием встроенных функций печати .NET.Позиция Adobe, похоже, заключается в том, чтобы «заставить пользователя просмотреть файл в Adobe Reader и нажать кнопку «Печать».Бесполезный.

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

Согласно ответу Яна Тревина, печать с использованием System.Drawing.Printing не поддерживается MS.Однако вы можете использовать новый метод System.Printing на основе WPF (я думать)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top