Nano Hash - криптовалюты, майнинг, программирование

Печать PDF-документов из приложения Windows 8

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

 onPrintTaskRequested: function (e) {
        var self = Application.navigator.pageControl,
            printTask = e.request.createPrintTask("Print Test Doc", function (args) {
                args.setSource(MSApp.getHtmlPrintDocumentSource(document));

                // Register the handler for print task completion event
                printTask.oncompleted = self.onPrintTaskCompleted;
            });
    }

Согласно документации, метод MSApp.getHhtmlPrintDocumentSource принимает определенный набор типов данных. Как указано в документации:

Это может быть корневой документ, документ в IFrame, фрагмент документа или документ SVG. Имейте в виду, что htmlDoc должен быть документом, а не элементом.

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


Ответы:


1

После проб и ошибок мне наконец удалось реализовать печать потока Base64, представляющего двоичный файл PDF из приложения Windows 8.

Я кодирую приложение в HTML/CSS/WinJS. По сути, вот краткое объяснение того, как это было достигнуто:

Создайте новый элемент <canvas> в файле default.html. Поместите его сразу после открытого тега элемента. Нравится:

<body role="application" class="app">
    <canvas id="pdf-render-output"></canvas>
    . 
    .
    .
</body>

Затем внутри файла default.css настройте несколько правил, а также запрос на печать. Нравится:

body > canvas {
    display: none;
}

.
. /* all your app's default css styles */
.

@media print {

    body > * {
       display:none;
       max-width: 100%;
    }

    html {
       max-width: 100%;
       border-top-color: none;
       border-top: 0;
    }

    body > canvas {
        display: block;
        border: none;
        max-width: 100%;
        width: 100%;
        height: 100%;
        position: relative;
    }
}

Следует отметить порядок, в котором правила объявляются в CSS. Важно размещать запрос для печати после объявления правил CSS по умолчанию.

После того, как это настроено, javascript обрабатывает все остальное. Основная идея состоит в том, чтобы отображать вывод PDF.js на «скрытый» холст в DOM. Когда объект документа отправляется на печать, запрашивается объявление носителя для печати CSS, чтобы все элементы под <body> были скрыты, кроме элемента холста. Вот javascript для печати только первой страницы в PDF:

 //Define a container for the Base64 data we'll use with PDF.js
 var pdfPrintData = {};

 //Function to render PDF to canvas and begin printing contract with Windows 8 OS
 printPrescription: function () {

        var self = Application.navigator.pageControl,
            printManager = Windows.Graphics.Printing.PrintManager.getForCurrentView();

        self.getPDF().done(function () {
            var pdfStream = pdfPrintData.base64,
                pdfFile = convertDataURIToBinary(pdfStream);

            PDFJS.disableWorker = true;
            PDFJS.getDocument(pdfFile).then(function (pdf) {

                var numPages = pdf.numPages,
                    renderCanvas = $('#pdf-render-output')[0];

                //setup canvas
                renderCanvas.height = pdf.getPage(1).data.getViewport(1).height;
                renderCanvas.width = pdf.getPage(1).data.getViewport(1).width;

                //Setup a render context for pdf.js to out a pdf file to the canvas.
                var renderContext = {
                        canvasContext: renderCanvas.getContext('2d'),
                        viewport: pdf.getPage(1).data.getViewport(1)
                    };

                //Bring up Windows 8 OS print after PDF is rendered to render context.
                pdf.getPage(1).data.render(renderContext).then(function () {
                    printManager.onprinttaskrequested = self.onPrintTaskRequested;
                    Windows.Graphics.Printing.PrintManager.showPrintUIAsync();
                });

            })

        });

},
onPrintTaskRequested: function (e) {
        var self = Application.navigator.pageControl,
            printTask = e.request.createPrintTask("Print Prescription", function (args) {
                args.setSource(MSApp.getHtmlPrintDocumentSource(document));
                printTask.oncompleted = self.onPrintTaskCompleted;
            });

},
onPrintTaskCompleted: function (e) {
        if (e.completion === Windows.Graphics.Printing.PrintTaskCompletion.failed) {
            console.log("[ERX]  :   Failed to print!");
        }
    }

Метод self.getPDF — это просто функция, которая извлекает поток данных Base64, и эти потоки устанавливаются в свойстве .base64 глобального объекта pdfPrintData. По какой-то причине мне не удалось отобразить PDF-файл с помощью pdf.js для динамического создания холста в динамически создаваемом документе. Мне пришлось отображать вывод метода рендеринга pdf.js на холст, уже присутствующий в DOM.

11.07.2013

2

Насколько мне известно, MSApp.getHtmlPrintDocumentSource(document) предназначен для использования с объектами HTML-документа и ни с чем другим.

Если вы можете предположить, что у вас Windows 8.1, вы можете попытаться собрать новый документ HTML из файла PDF, экспортировав каждую страницу в растровое изображение, используя PdfPage.RenderToStreamAsync. В MSDN есть пример проекта для средства просмотра PDF, использующего этот новый API, где вы можете узнать, как использовать этот метод.

Если вы не можете принять Windows 8.1 и вам нужна поддержка обычной Windows 8 или Windows RT (ARM), вам может потребоваться использовать стороннюю библиотеку для создания растровых изображений или для совместной печати.

Amyuni PDF Creator для WinRT, например может распечатать для вас. Отказ от ответственности: в настоящее время я работаю в компании, разрабатывающей библиотеку

08.07.2013
  • Спасибо за советы. Я нашел Amyuni PDF Creator во время поиска в Google. Есть ли бесплатная пробная версия для использования программного обеспечения? Кроме того, вы упомянули, что вам может понадобиться использовать стороннюю библиотеку для создания растровых изображений. Вы имеете в виду что-то вроде PDF.js? 08.07.2013
  • @ariestav Существует 30-дневная бесплатная пробная версия с бесплатной поддержкой. Говоря о сторонней библиотеке, я имел в виду, что вы не сможете печатать только с помощью WinRT API, поэтому я фактически имел в виду любую стороннюю библиотеку, коммерческую или с открытым исходным кодом. Я изо всех сил стараюсь играть честно, когда отвечаю на вопросы в SO. 08.07.2013
  • Что касается PDF.js, я более-менее знаю, что он делает, но никогда им не пользовался, поэтому не знаю, можно ли его использовать для печати или растеризации. 08.07.2013
  • У Amyuni есть отдельные файлы для разных архитектур. Моя сборка настроена как AnyCPU в диспетчере конфигурации VS2012. Как бы я включил его, учитывая мой процесс сборки? 09.07.2013
  • @yms pdf.js может не работать как есть. Я пробовал это раньше для рендеринга PDF-файлов и столкнулся с проблемой, когда шрифты не загружались. он пытается вставить теги <script>, которые не будут работать с winjs. если вы попробуете свои силы в pdf.js - будет хорошо поделиться своими выводами на SO. 09.07.2013
  • @aristav Библиотека является собственной библиотекой, а не dotnet, поэтому для каждой архитектуры у нее разные DLL. Что касается вашего вопроса, у вас есть два варианта: вы создаете еще две копии файла проекта, используя Amyuni PDF Creator, затем добавляете новые проекты в решение и настраиваете каждый проект для одной архитектуры ЦП. Все проекты будут использовать одни и те же файлы исходного кода, поэтому дублироваться будет только файл проекта. 09.07.2013
  • Другой известный мне вариант позволяет сохранить только один проект, но требует редактирования файла проекта вручную в текстовом редакторе. Подробнее см. в этом вопросе: Условно используйте 32 /64-битная ссылка при сборке в Visual Studio 09.07.2013
  • Я попытался создать пустой HTML-документ с помощью javascript, затем отобразить PDF-файл в контейнере холста в этом HTML-документе, а затем использовать его в качестве исходного параметра для getHtmlPrintDocumentSource. Я использую метод рендеринга PDF.js для рендеринга, но он не работает. Кто-нибудь знает, нужен ли pdf.js элемент dom, который визуально отображается в приложении? 11.07.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..