Создание PDF с использованием EVOPdf, WebAPI и AngularJS

У меня возникла проблема с рендерингом PDF-файла с помощью EVOPdf из контроллера WebAPI в приложение AngularJS.

Это мой код до сих пор:

Угловой вызов:

var url = 'api/form/build/' + id;

$http.get(url, null, { responseType: 'arraybuffer' })
.success(function (data) {
    var file = new Blob([data], { type: 'application/pdf' });

    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(file);
    }
    else {
        var objectUrl = URL.createObjectURL(file);
    window.open(objectUrl);
    }
});

Метод API-контроллера:

var url = "http://localhost/index.html#/form/build/" + id;

#region PDF Document Setup
HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

htmlToPdfConverter.LicenseKey = "4W9+bn19bn5ue2B+bn1/YH98YHd3d3c=";
//htmlToPdfConverter.HtmlViewerWidth = 1024; //default
htmlToPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
htmlToPdfConverter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait;
htmlToPdfConverter.ConversionDelay = 3;
htmlToPdfConverter.MediaType = "print";

htmlToPdfConverter.PdfDocumentOptions.LeftMargin = 10;
htmlToPdfConverter.PdfDocumentOptions.RightMargin = 10;
htmlToPdfConverter.PdfDocumentOptions.TopMargin = 10;
htmlToPdfConverter.PdfDocumentOptions.BottomMargin = 10;
htmlToPdfConverter.PdfDocumentOptions.TopSpacing = 10;
htmlToPdfConverter.PdfDocumentOptions.BottomSpacing = 10;
htmlToPdfConverter.PdfDocumentOptions.ColorSpace = ColorSpace.RGB;

// Set HTML content destination in PDF page
htmlToPdfConverter.PdfDocumentOptions.Width = 640;

htmlToPdfConverter.PdfDocumentOptions.FitWidth = true;
htmlToPdfConverter.PdfDocumentOptions.StretchToFit = true; 
#endregion

byte[] outPdfBuffer = htmlToPdfConverter.ConvertUrl(url);

string outPdfFile = @"c:\temp\forms\" + id + ".pdf";
System.IO.File.WriteAllBytes(outPdfFile, outPdfBuffer);


HttpResponseMessage result = null;
result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new ByteArrayContent(outPdfBuffer.ToArray());
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "filename.pdf";
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

return result;

Когда я проверяю PDF-файл, который я записываю с помощью WriteAllBytes, он отображается отлично, но когда он возвращается через вызов Angular и открывается в Adobe Reader, я получаю всплывающее сообщение об ошибке "Недопустимое цветовое пространство" несколько раз, но документ не открывается. Когда я меняю цветовое пространство на GrayScale, PDF-файл открывается, но он пустой.

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

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

Заранее благодарю за любую помощь.

С уважением, Иоганн.


person Johann Marx    schedule 11.08.2015    source источник
comment
Я только что прошел через это самое! К сожалению, в данный момент только на моем телефоне, поэтому я не могу дать вам достойный ответ, но чтобы дать вам понять, что это как-то связано с тем, что ajax не может загрузить blob / pdf. Попробуйте использовать filesave.js. Мне удалось заставить его работать для всех, кроме сафари на Mac (пока).   -  person Le-roy Staines    schedule 12.08.2016
comment
У меня точно такая же проблема... Вы нашли решение этой проблемы? Я просто застрял :(   -  person Nizar    schedule 20.04.2017
comment
То же самое. У кого-нибудь есть решение?   -  person Kristóf Tóth    schedule 17.05.2019


Ответы (3)


Проблема вроде как на стороне клиента, не правильно разбираются символы в ответе. Для тех, кто борется с этим, я нашел свое решение здесь: SO Question< /а>

person Kristóf Tóth    schedule 20.05.2019

Пробовали ли вы безголовый Chrome? Здесь — хорошая статья на эту тему. Я использовал https://github.com/puppeteer/puppeteer для этой цели, и это было легко интегрируемое решение.

person Jakub Kubista    schedule 03.06.2020

// устанавливаем пакет puppeteer-core npm cmd

            npm i puppeteer-core
            # or "yarn add puppeteer-core"
    
           <!-- example.js start-->

       const puppeteer = require('puppeteer');
    
        (async () => {
          const browser = await puppeteer.launch();
          const page = await browser.newPage();
          await page.goto('https://example.com');
          await page.screenshot({ path: 'example.png' });
        
          await browser.close();
        })();
  • Выполнить скрипт в командной строке

    пример узла.js

    Puppeteer устанавливает начальный размер страницы 800×600 пикселей, что определяет размер снимка экрана. Размер страницы можно настроить с помощью Page.setViewport().

    Пример - создать PDF.

  • Сохранить файл как hn.js

const puppeteer = require('кукловод');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://news.ycombinator.com', {
    waitUntil: 'networkidle2',
  });
  await page.pdf({ path: 'hn.pdf', format: 'a4' });

  await browser.close();
})();
  • Выполнить скрипт в командной строке

    node hn.js См. Page.pdf() для получения дополнительной информации о создании PDF-файлов.

    Пример — оценка скрипта в контексте страницы

  • Сохраните файл как get-dimensions.js

const puppeteer = require('кукловод');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // Get the "viewport" of the page, as reported by the page.
  const dimensions = await page.evaluate(() => {
    return {
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio,
    };
  });

  console.log('Dimensions:', dimensions);

  await browser.close();
})();
  • Выполнить скрипт в командной строке

    узел get-dimensions.js

    См. Page.evaluate() для получения дополнительной информации об оценке и связанных с ней методах, таких как AssessmentOnNewDocument и exposeFunction.

person Teena Pamecha    schedule 20.02.2021