Голанг: как направлять

Как создать PDF в Go: пошаговое руководство

Следите за тем, как мы создаем счет в формате PDF с нуля

Введение

Если вы не жили под скалой последние 20 лет, вы должны знать, что с PDF-файлами может быть сложно работать, особенно при работе с динамическим контентом (например, с персонализированной информацией). В случае со счетами-фактурами это становится все более заметным и очевидным.

Я имею в виду, что никто не хочет вручную изменять информацию в каждом PDF-файле. Они?

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

И это именно то, что мы будем делать здесь.

Стоит отметить, что в некоторых случаях пользователь может сгенерировать счет в формате PDF в интерфейсе, а в других случаях система сгенерирует его в фоновом режиме и отправит пользователю по электронной почте в конце цикла выставления счетов. Особо остановимся на последнем.

📌Отказ от ответственности: я выбрал UniDoc, чтобы помочь мне с этим, потому что он имеет широкий спектр настроек, обширную документацию, примеры и, честно говоря, прост в настройке и использовании. Но есть пара других пакетов PDF Go, которые вы также можете использовать, например Gopdf, Gofpdf (устаревший) и Pdfcpu. У PDFTron также есть Go SDK, но его нет в родном Go, поэтому он требует некоторых зависимостей.

Просто обратите внимание, что какими бы ни были ваши предпочтения, логика остается неизменной; пакет - это просто средство для достижения цели.

Чему вы научитесь

  1. Почему вы должны набросать счет в формате PDF, прежде чем писать код для его генерации
  2. Как визуализировать для него простой архитектурный проект
  3. Как создать invoice-pdf.go файл
  4. Как создать счет в формате PDF: общая структура, шапка, фирменный бланк, позиции счета, нижний колонтитул
  5. Как сгенерировать окончательный вывод вашего счета в формате PDF
  6. [Бонус] Почему не стоит использовать float с деньгами и валютой

Предпосылки

  • Знание модулей Go и Go
  • Go 1.18+ установлен на вашем компьютере

Начиная

Вы можете следовать здесь или взглянуть на базу кода в этом репозитории GitHub:



GitHub — marvinhosea/invoice-pdf-generator
github.com



Сначала перейдите в каталог, в котором вы можете создавать приложения 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.

В корневом каталоге проекта в терминале запустите эту команду, чтобы добавить thegodotenvpackage, который поможет прочитать наши переменные среды:

go get -u github.com/joho/godotenv

Далее давайте создадим каталог config в корневом каталоге проекта и создадим внутри него aconfig.gofile. Затем скопируйте в него содержимое ниже:

В строке 14 мы загрузили файл.env, чтобы получить переменные среды из файла.env, который являетсяUNIDOC_LICENSE_API_KEY в этом проекте. Остальная часть кода просто проверяет, установлен ли ключ, и возвращает структуру UniDocConfig или ошибку.

Мы почти на месте. Давайте создадим каталог invoice-pdf.gofile внутриinternal и добавим в него наш код генерации PDF, который является душой нашего простого проекта генератора PDF-счетов.

Но перед этим вернитесь в корневой каталог проекта в терминале и добавьте пакет UniDoc Go, как показано ниже:

go get -u github.com/unidoc/unipdf/v3

👉Примечание. Эта статья основана на версии 3 пакета.

Теперь перейдите во внутренний каталог проекта и во внутреннем каталоге создайте invoice-pdf.go и добавьте следующий код:

Общая структура: краткий анализ ☝️

В строке 11 в theinvoice-pdf.gofile мы добавили структуру Client с создателем свойств, который содержит наш экземпляр создателя PDF. Экземпляр создателя имеет методы, которые помогают манипулировать документом PDF и создавать красивый счет в формате PDF.

В строке 26 мы определили стили ячеек, которые будут добавлены в документ.

В строке 88, используя theconfigpackage сGetUniDocCredfunction, мы получили наш ключ API из переменной среды, которую мы добавили в the.env файл. Мы увидим сообщение об ошибке, если нам не удастся получить документ.

В строке 93, поскольку наше использование UniDoc измеряется, мы должны были добавить ключ API нашей учетной записи, полученный в строке 88.

В строке 98 мы инициализировали и создали экземпляр newcreatorinstance.

В строке 99 мы устанавливаем поля страницы PDF.

В строке 101 мы вызвали theClient structgeneratePdfmethod и передали ему экземпляр инвойса.

Давайте немного углубимся в этот метод.

Создание заголовка счета

Строки со 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 происходит волшебство. Мы записали thecreatorblocks в выходной документ, который в данном случае является PDF-файлом, и метод создает PDF-файл по указанному пути.

☝️Помните: не забудьте добавить.pdfextension к вашему пути

Наконец, вернемся к файлу ourmain.gofile и добавим приведенный ниже код.

В строках 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 за эту статью. Все мысли, мнения, код, изображения, записи и т. д. принадлежат мне.