Голанг: как направлять
Как создать PDF в Go: пошаговое руководство
Следите за тем, как мы создаем счет в формате PDF с нуля
Введение
Если вы не жили под скалой последние 20 лет, вы должны знать, что с PDF-файлами может быть сложно работать, особенно при работе с динамическим контентом (например, с персонализированной информацией). В случае со счетами-фактурами это становится все более заметным и очевидным.
Я имею в виду, что никто не хочет вручную изменять информацию в каждом PDF-файле. Они?
Было бы намного проще, если бы это каким-то образом хранилось в базе данных и создавался скрипт, извлекающий необходимые данные для передачи их в библиотеку. Таким образом, вы можете масштабировать его (и избавить себя от головной боли в процессе).
И это именно то, что мы будем делать здесь.
Стоит отметить, что в некоторых случаях пользователь может сгенерировать счет в формате PDF в интерфейсе, а в других случаях система сгенерирует его в фоновом режиме и отправит пользователю по электронной почте в конце цикла выставления счетов. Особо остановимся на последнем.
📌Отказ от ответственности: я выбрал UniDoc, чтобы помочь мне с этим, потому что он имеет широкий спектр настроек, обширную документацию, примеры и, честно говоря, прост в настройке и использовании. Но есть пара других пакетов PDF Go, которые вы также можете использовать, например Gopdf, Gofpdf (устаревший) и Pdfcpu. У PDFTron также есть Go SDK, но его нет в родном Go, поэтому он требует некоторых зависимостей.
Просто обратите внимание, что какими бы ни были ваши предпочтения, логика остается неизменной; пакет - это просто средство для достижения цели.
Чему вы научитесь
- Почему вы должны набросать счет в формате PDF, прежде чем писать код для его генерации
- Как визуализировать для него простой архитектурный проект
- Как создать
invoice-pdf.go
файл - Как создать счет в формате PDF: общая структура, шапка, фирменный бланк, позиции счета, нижний колонтитул
- Как сгенерировать окончательный вывод вашего счета в формате PDF
- [Бонус] Почему не стоит использовать float с деньгами и валютой
Предпосылки
- Знание модулей Go и Go
- Go 1.18+ установлен на вашем компьютере
Начиная
Вы можете следовать здесь или взглянуть на базу кода в этом репозитории GitHub:
Сначала перейдите в каталог, в котором вы можете создавать приложения Go, и создайте новый каталог с именем invoice-pdf-generator.
Теперь перейдите в корневой каталог проекта и создайте модуль Go, выполнив приведенные ниже инструкции в терминале в корневом каталоге проекта:
go mod init github.com/username/invoice-pdf-generator
👉 Примечание. Замените свое имя пользователя Github на [имя пользователя] выше.
📖 Дополнительная литература: мы будем использовать модули Go для управления зависимостями нашего проекта; узнать о них подробнее можно здесь.
Эскиз PDF
Теперь, когда мы настроили наш проект и готовы к написанию кода, давайте создадим простой визуальный набросок того, как должен выглядеть наш счет в формате PDF:
💡 Прежде чем приступить к любому проекту, я лично убедился, что лучше всего представить себе, каким должен быть результат. Таким образом, вы можете сосредоточиться на том, что нужно сделать, и линейно структурировать свой мыслительный процесс для решения проблем.
На изображении выше вы можете увидеть блоки данных дизайна для нашего счета в формате PDF.
Простой архитектурный дизайн
Давайте лучше разберемся с потоком данных и визуализируем архитектурный проект:
Здесь наша служба создания PDF-файлов счетов представляет собой простую программу, которая имитирует прием запросов данных счетов-фактур с данными, предоставленными для создания PDF-файла счета-фактуры, который затем сохраняется в корзине s3 или предпочтительном носителе.
Откройте проект в вашей любимой Go IDE и создайте файл amain.go
. Добавьте объявление пакета как main и основную функцию:
👉 Примечание. Мы вернемся к файлу
main.go
и добавим код позже.
Затем внутри корневого каталога проекта создайте новый каталог с именем internal
. Внутри каталога internal
создайте invoice-data.go
и скопируйте содержимое ниже в invoice-data.go
📖 Дополнительная литература: Подробнее об использовании каталога
internal
читайте в разделе Перейти здесь)
Функция NewInvoiceData
— это простой конструктор для нашей InvoiceData
структуры, которая используется для создания новых данных InvoiceData
.
Оператор NewInvoiceData
допускает interface
(любой тип данных), а оператор switch
фильтрует разрешенный тип данных. Это намеренно добавлено.
👉 Примечание. Я проведу рефакторинг этой базы кода с помощью универсальных шаблонов Go в будущей статье «Глубокие дженерики Go».
Вы, возможно, заметили, что в строках 33, 35, 37 и 39 я умножил priceValue
на 100 и разделил на 100 в строках 19 и 25. В результате умножение priceValue
на 100 (или подход в евроцентах) уменьшает пропущенные расчеты. в нашем сервисе выставления счетов.
💡 Совет эксперта: при работе с деньгами или валютными значениями не рекомендуется использовать float. Компьютеры обрабатывают числа с плавающей точкой по основанию 2, а не по основанию 10 (которое мы используем в денежных расчетах). Более подробную информацию можно найти здесь".
👉 Примечание.
CalculateTotalAmount
вычисляет общую сумму одной позиции счета путем умножения ее количества и цены.
В том же каталоге скопируйте следующее содержимое в файл invoice.go
:
Выше вы увидите, что мы добавили функциюCreateInvoice
в файлinvoice.go
, которая принимает бизнесname
, address
и частьinvoiceItems
для создания экземпляраInvoice
.
CalculateInvoiceTotalAmount
вычислил общую сумму счета, перебирая invoiceItems
срез (массив) и получая каждыйInvoiceData
TotalAmount
с помощью методаCalculateTotalAmount
.
В строке 24 мы преобразовали целое число в число с плавающей запятой, а затем разделили его на 100 (см. здесь для объяснения).
Теперь, когда это сделано, давайте получим ключ API, необходимый для заполнения этого счета в формате PDF.
Создание файла invoice-pdf.go
Перейдите в UniDoc и получите бесплатный ключ API, нажав здесь.
Не забудьте скопировать ключ API после его создания.
🎥 Видео: короткое руководство, которое я нашел в Интернете, может оказаться полезным
Вернемся к нашему проекту. В корневом каталоге нашего проекта создайте файл среды .env
и добавьте содержимое ниже:
👉Примечание. Если вы клонируете проект с GitHub, скопируйте файл .env.example в файл .env.
🛑НЕ фиксируйте файл .env с ключом API.
Замените [Your_API_Key] ключом вашей учетной записи из вашей учетной записи UniDoc.
В корневом каталоге проекта в терминале запустите эту команду, чтобы добавить thegodotenv
package, который поможет прочитать наши переменные среды:
go get -u github.com/joho/godotenv
Далее давайте создадим каталог config в корневом каталоге проекта и создадим внутри него aconfig.go
file. Затем скопируйте в него содержимое ниже:
В строке 14 мы загрузили файл.env
, чтобы получить переменные среды из файла.env
, который являетсяUNIDOC_LICENSE_API_KEY
в этом проекте. Остальная часть кода просто проверяет, установлен ли ключ, и возвращает структуру UniDocConfig или ошибку.
Мы почти на месте. Давайте создадим каталог invoice-pdf.go
file внутриinternal
и добавим в него наш код генерации PDF, который является душой нашего простого проекта генератора PDF-счетов.
Но перед этим вернитесь в корневой каталог проекта в терминале и добавьте пакет UniDoc Go, как показано ниже:
go get -u github.com/unidoc/unipdf/v3
👉Примечание. Эта статья основана на версии 3 пакета.
Теперь перейдите во внутренний каталог проекта и во внутреннем каталоге создайте invoice-pdf.go
и добавьте следующий код:
Общая структура: краткий анализ ☝️
В строке 11 в theinvoice-pdf.go
file мы добавили структуру Client
с создателем свойств, который содержит наш экземпляр создателя PDF. Экземпляр создателя имеет методы, которые помогают манипулировать документом PDF и создавать красивый счет в формате PDF.
В строке 26 мы определили стили ячеек, которые будут добавлены в документ.
В строке 88, используя theconfig
package сGetUniDocCred
function, мы получили наш ключ API из переменной среды, которую мы добавили в the.env
файл. Мы увидим сообщение об ошибке, если нам не удастся получить документ.
В строке 93, поскольку наше использование UniDoc измеряется, мы должны были добавить ключ API нашей учетной записи, полученный в строке 88.
В строке 98 мы инициализировали и создали экземпляр newcreator
instance.
В строке 99 мы устанавливаем поля страницы PDF.
В строке 101 мы вызвали theClient
structgeneratePdf
method и передали ему экземпляр инвойса.
Давайте немного углубимся в этот метод.
Создание заголовка счета
Строки со 110 по 116 начали создание заголовка нашего счета, прямоугольного блока высотой 120 со светло-серым фоном. Вы можете поэкспериментировать с аргументом в зависимости от ваших предпочтений.
В строке 118 мы создали новый стиль текста и присвоили ему размер шрифта 50 в строке 119.
После инициализации стиля мы создали таблицу с одним столбцом и нулевыми полями слева, справа и снизу, а также верхними полями 20 в строках 121 и 122.
В строке 123 мы создали новый центрированный блок ячеек с новым абзацем текстового стиля, созданным в строке 118, и поместили его в текущую позицию в нашей таблице. Новый абзац содержит содержимое заголовка.
В строке 127 мы создали наш первый блок таблицы.
Создание фирменного бланка счета-фактуры
Теперь, когда мы добавили заголовок счета, давайте добавим бизнес-информацию.
Со строки 132 мы перешли к строке 176, используя метод thewriteInvoice
, который принимает экземпляр счета.
В строке 177 все, что мы сделали, — это создали еще один стиль текста для фирменного бланка таблицы.
Со строк со 179 по 192 мы создали еще одну таблицу с двумя столбцами (вместо одного) и верхним полем 50. К этому моменту вы должны быть знакомы с кодом создания блока таблицы.
Добавление позиций счета
С 195 по 204 мы инициализировали таблицу, содержащую данные о наших элементах счета. Процесс такой же, как и раньше, но с некоторыми настройками, такими как ширина столбцов, размер шрифта и т. д.
Затем со строк 207 по 222 мы нарисовали заголовок таблицы позиций счета.
👉 Примечание. Это должно быть очень знакомо, если вы знаете HTML и CSS.
В строке 223 мы прошлись по каждому пункту счета и добавили соответствующие данные в ячейки таблицы элементов счета. Затем мы соответствующим образом расположили их внутри таблицы на их текущих позициях.
Мы завершили создание таблицы элементов счета в строке 241, что привело к блокировке таблицы.
[извините, я должен был 😂]
Создание нижнего колонтитула счета-фактуры
Общеизвестно, что в счете-фактуре должна быть сводка его позиций и общая сумма. Итак, давайте закончим, добавив это в нижний колонтитул документа:
Начиная со строки 246, мы создали еще одну таблицу с двенадцатью столбцами и задали ширину столбцов в строке 253.
В строках 257 и 261 мы предоставили данные ячейки таблицы нижнего колонтитула.
👉 Примечание. Если бы ваш код был успешным, он бы вернул нулевую ошибку в строке 132.
В строке 137 происходит волшебство. Мы записали thecreator
blocks в выходной документ, который в данном случае является PDF-файлом, и метод создает PDF-файл по указанному пути.
☝️Помните: не забудьте добавить
Наконец, вернемся к файлу ourmain.go
file и добавим приведенный ниже код.
В строках 10 и 14 мы просто собрали новые объекты данных счета.
[Предположим, что это запрос данных счета-фактуры]
А в строке 19 мы создали срез InvoiceData
как коллекцию элементов счета.
Коллекция созданных элементов счета-фактуры использовалась для создания экземпляра счета-фактуры в строке 22, который использовался для создания PDF-файла счета-фактуры в строке 23.
Заканчивать
Теперь запустите программу в терминале. Если ошибки нет, вы должны получить следующий вывод:
The Total Invoice Amount is: 3201.200000
Теперь идем дальше и проверяем корневую директорию проекта. Вы должны найти файл счета в формате pdf, который выглядит следующим образом:
И это все для простого счета в формате PDF!
Вопросы/Проблемы/Проблемы? Разместите их ниже в комментариях👇, и я обязательно отвечу на них как можно быстрее.
Заключение
Создавать PDF-файлы, особенно с динамическим содержимым, непросто. Но, к счастью, есть несколько вариантов, которые могут вам помочь — от дизайна до архитектуры и реализации системы.
Очевидно, что я не стал вдаваться в подробности в этой статье, но, надеюсь, я установил стандартные блоки, чтобы вы могли самостоятельно настраивать счета-фактуры в формате PDF с помощью Go.
Выводы:
- Перед внедрением создайте черновик визуального документа (pdf).
- Построение диаграммы архитектуры системы дает представление о проекте
- НЕ используйте плавающий тип данных для расчета денег и валюты
- НЕ фиксируйте и не отслеживайте файлы среды проекта с ключами с помощью git
🚀 Дополнительное задание: добавьте дополнительные реализации в кодовую базу, например, храните PDF-файлы счетов-фактур в корзине S3.
Исходный код
Вы можете найти исходный код проекта по ссылке GitHub ниже:
Другие статьи для рассмотрения
Оптимизируйте свою производительность с помощью «Air
Лучший метод Go для динамической перезагрузки с помощью Dockermedium.com»
Раскрытие информации: в соответствии с правилами и рекомендациями Medium.com я публично подтверждаю финансовую компенсацию от UniDoc за эту статью. Все мысли, мнения, код, изображения, записи и т. д. принадлежат мне.