Как я могу создать PDF на основе представления в приложении Rails - PullRequest
0 голосов
/ 04 июля 2019

Обзор

Я хочу создать PDF-файл на основе представления в приложении Rails, используя модели, которые есть у меня в самом приложении (т. Е. Посещение определенной конечной точки приведет к созданию отчета в формате PDF).

Вопрос

Какой стандартный / эффективный способ сделать это?

Вещи, которые я пробовал

Я пытался использовать wicked_pdf и PDFKit . Оба из которых зависят от wkhtmltopdf .

Но я столкнулся с несколькими проблемами:

  • Рендеринг PDF занимает много времени
  • Невозможно использовать существующие таблицы стилей, потому что некоторые CSS, такие как flexbox, не поддерживаются
  • Форматирование выключено
  • ES6 не поддерживается
  • Отладка Javascript сложна
  • Опция отладки show_as_html для wicked_pdf не может достоверно показать вам, как PDF отображает
  • Некоторые библиотеки JS, такие как ChatJS и Google Maps, отображаются неправильно
  • Использование javascript_delay выглядит серебряной пулей, но это не решает проблемы со сторонними библиотеками

Должен быть лучший способ ...

Ответы [ 2 ]

1 голос
/ 04 июля 2019

Единственный подход, который я могу придумать для достижения чего-то подобного, - это решить вопросы, которые вы представляете 1 к 1. По моему опыту, wicked_pdf - лучший путь.Относительно проблем, с которыми вы сталкиваетесь:

  1. Рендеринг PDF занимает много времени: вы можете кэшировать PDF-файлы и сохранять их на своем сервере (с помощью скрепки, activestorage, shrine или другого файлового менеджера, которыйработает с рельсами).Таким образом, генерация PDF займет всего один раз.
  2. Невозможно использовать существующие таблицы стилей, потому что некоторые CSS, такие как flexbox, не поддерживаются: как указано github, эта проблема , flexbox неполностью поддерживается, хотя есть несколько вещей, которые работают, например, изменение display: flex на display: -webkit-box.Если частичное исправление, найденное в этой проблеме, не работает, решение будет заключаться в использовании негибкого представления для создания PDF.
  3. Форматирование выключено: это, скорее всего, связано с неработающим CSSиз-за неподдерживаемых свойств CSS.Вы можете исправить их один за другим, их не должно быть много, так как wicked_pdf поддерживает наиболее распространенные и используемые свойства CSS (может быть исключение flexbox)
  4. ES6 не поддерживается: вы правы.Для этих представлений вам придется исправить обычный javascript.
  5. Отладка Javascript сложна: ключевым моментом отладки javascript и понимания его работы является удаление практически всех возможных анимаций.Например, если вы используете библиотеку с «рендерингом анимации» (скажем, у карт google эффект затухания), wicked_pdf начнет рендеринг карт google после того, как вы удалите эти эффекты, чтобы не было ни «затухания», ни«delay», в противном случае wicked_pdf будет делать «снимок экрана» страницы, отображаемой с секундой 0.
  6. Параметр отладки show_as_html для wicked_pdf не показывает, как PDF отображает надежно: правильно, это нужно сделатьwith (5) и (3).
  7. Некоторые библиотеки JS, такие как ChatJS и Google Maps, отображают некорректно: как указано в 5, это связано с «задержками» в методе визуализации.Существует новый метод API, поддерживаемый wicked_pdf, который называется javascript_delay, и вы можете найти здесь проблему

Надеюсь, это поможет

0 голосов
/ 05 июля 2019

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

Но если вы не хотите использовать генератор pdf (wickedpdf или pdfkit) для его генерации на сервере и у вас есть html, вы можете использовать функцию печати javascript, а тег, который вы не хотите включать, можно скрыть от печать с использованием носителя печати css.

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

<!DOCTYPE html>
<html>
<body>
<style type="text/css">
@page { size: auto;  margin: 0mm; }
@media print {
  .hide_printing {
      display :  none;
  }
}
</style>
<p>Click the button to print the current page.</p>

<button class="hide_printing" onclick="myFunction()">Print this page</button>

<script>
function myFunction() {
  window.print();
}
</script>

</body>
</html>
...