Все делается достаточно банально и просто. С поиском решения весь процесс занял не более пары часов. Правда нужно использовать сторонние средства (уже слышу ехидные усмешки разработчиков node.js). К сожалению, полноценного процесса на Go на момент написания я не нашел. Используем wkhtmltopdf.
Он понравился прежде всего за простоту установки.
К примеру для Ubuntu:
Но на сервере тогда нужно будет настраивать виртуальный xserver. Проще всего это делать с помощью утилиты xvfb.
Но можно скачать с сайта wkhtmltopdf готовую сборку и установить с помощью команды
Тогда не нужно настраивать никаких виртуальных X-ов.
Установка библиотеки в Go
Ранее мы предусмотрительно создали специальный BaseController, в котором описываем общие функции. Как результат здесь мы можем глобально переопределить некоторые методы для всех наших контроллеров.
Итак, в BaseController.go добавляем функцию
С помощью ее мы переопределим стандартную функцию вывода контекста на нашу, в которой мы смотрим, есть ли параметр «export» и значение этого параметра «pdf».
Так же саму функцию ToPDF() я вынес в отдельный файл pdf.go в папке «controllers»
Если сжато, то здесь мы подключаем нашу библиотеку (именуем ее как wkhtmltopdf для удобства). В самой функции создаем новый документ, определяем нужное нам разрешение (Dpi) и размер страницы. Создаем страницу из содержимого, принимаемого через параметр. Добавляем полученную страницу в документ. Запускаем генерацию документа через «Create» и отдаем результат.
Таким образом все содержимое перед выводом можно экспортировать в pdf. Достаточно в адресе странички набрать bygolang.org?export=pdf.
Заголовки будут прописаны соответствующие. К сожалению, корректно настроить на моем сервере wkhtmltopdf у меня не получилось, ввиду особенности самого сервера, но на обычном компьютере этого оказалось достаточно. На сервере контент отдает как на мобильном устройстве ввиду особенных настроек разрешения экрана.
Оригинал статьи посмотреть а так же проверить как работает данный способ можно здесь.
Он понравился прежде всего за простоту установки.
К примеру для Ubuntu:
apt-get install wkhtmltopdf
apt-get install xvfb
echo -e '#!/bin/bash\nxvfb-run -a --server-args="-screen 0, 1024x768x24" /usr/bin/wkhtmltopdf -q $*' > /usr/bin/wkhtmltopdf.sh
chmod a+x /usr/bin/wkhtmltopdf.sh
ln -s /usr/bin/wkhtmltopdf.sh /usr/local/bin/wkhtmltopdf
Но на сервере тогда нужно будет настраивать виртуальный xserver. Проще всего это делать с помощью утилиты xvfb.
Но можно скачать с сайта wkhtmltopdf готовую сборку и установить с помощью команды
sudo dpkg -i name_packet.deb
Тогда не нужно настраивать никаких виртуальных X-ов.
Установка библиотеки в Go
go get github.com/SebastiaanKlippert/go-wkhtmltopdf
Ранее мы предусмотрительно создали специальный BaseController, в котором описываем общие функции. Как результат здесь мы можем глобально переопределить некоторые методы для всех наших контроллеров.
Итак, в BaseController.go добавляем функцию
func (b *BaseController) Render() error {
if !b.EnableRender {
return nil
}
rb, err := b.RenderBytes()
if err != nil {
return err
}
export := b.GetString("export")
if export == "pdf" {
b.Ctx.Output.Header("Content-Type", "application/pdf; charset=utf-8")
return b.Ctx.Output.Body(ToPDF(rb))
}
if b.Ctx.ResponseWriter.Header().Get("Content-Type") == "" {
b.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8")
}
return b.Ctx.Output.Body(rb)
}
С помощью ее мы переопределим стандартную функцию вывода контекста на нашу, в которой мы смотрим, есть ли параметр «export» и значение этого параметра «pdf».
Так же саму функцию ToPDF() я вынес в отдельный файл pdf.go в папке «controllers»
package controllers
import (
"bytes"
"log"
"github.com/astaxie/beego"
wkhtmltopdf "github.com/SebastiaanKlippert/go-wkhtmltopdf"
)
// ToPDF ...
// Generate PDF document from HTML
func ToPDF(htmlStr []byte) []byte {
// Create new PDF generator
pdfg, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
log.Fatal(err)
}
pdfg.Dpi.Set(600)
pdfg.NoCollate.Set(false)
pdfg.PageSize.Set(wkhtmltopdf.PageSizeA4)
pdfg.MarginBottom.Set(40)
page1 := wkhtmltopdf.NewPageReader(bytes.NewReader(htmlStr))
pdfg.AddPage(page1)
// Create PDF document in internal buffer
err = pdfg.Create()
if err != nil {
beego.Trace(err)
}
// Return buffer contents
return pdfg.Bytes()
}
Если сжато, то здесь мы подключаем нашу библиотеку (именуем ее как wkhtmltopdf для удобства). В самой функции создаем новый документ, определяем нужное нам разрешение (Dpi) и размер страницы. Создаем страницу из содержимого, принимаемого через параметр. Добавляем полученную страницу в документ. Запускаем генерацию документа через «Create» и отдаем результат.
Таким образом все содержимое перед выводом можно экспортировать в pdf. Достаточно в адресе странички набрать bygolang.org?export=pdf.
Заголовки будут прописаны соответствующие. К сожалению, корректно настроить на моем сервере wkhtmltopdf у меня не получилось, ввиду особенности самого сервера, но на обычном компьютере этого оказалось достаточно. На сервере контент отдает как на мобильном устройстве ввиду особенных настроек разрешения экрана.
Оригинал статьи посмотреть а так же проверить как работает данный способ можно здесь.
Комментарии (5)
Boggard
11.05.2018 14:10wkhtmltopdf довольно старая утилита. последний стабильный релиз в 2016. К сожалению, не поддерживает массу полезных свойств CSS при конвертации html>pdf. Программная разбивка на страницы и заголовки на каждой странице идут с большим трудом.
Стоит посмотреть в сторону PhantomJs или еще лучше Electron как более современные «аналоги»
manefesto
По факту это не нативный рендер pdf, а использование сторонней утилиты
Ihariv Автор
К сожалению, да. Возможно заголовок слегка вводит в заблуждение, но поменять его нет возможности. Спасибо за замечание, учту это при написании следущюей заметки
anjensan
Ihariv Автор
Выдает системное сообщение, что я не могу добавлять в hub Go свои статьи