Умные коллеги найдут способ заниматься на работе чем угодно, кроме самой работы!
(Подсмотрено в "Трудовыебудни" - с юмором про работу и жизнь)
P.S. и советую заценить подарочный набор миллиардера с настоящим миллиардом долларов!
(Подсмотрено в "Трудовыебудни" - с юмором про работу и жизнь)
P.S. и советую заценить подарочный набор миллиардера с настоящим миллиардом долларов!
Я уже в прошлом посте писал, у меня была проблема с разлинейкой внутри ячейки для списка. Мне подсказали что можно просто добавить горизонтальные строки, так и сделал но теперь не удается правильно распечатать, границы печати просто уходят и не пойму как их закрепить. Если найдете минуту времени кто разбирается,
напишите пожалуйста в ЛС. Я в телегу или Макс или на почту скину образец. Заранее большое спасибо.
Собственно вопрос как внутри ячейки в уже готовом шаблоне сделать 3 линии, что бы было как на фото 4 строки для записи. Спасибо.
Достаточно частая задача — сравнение нескольких списков и выявление повторов между ними.
Допустим, у вас четыре списка (напр., email или товаров) и нужно понять, какие значения из каких списков пересекаются друг с другом (не усложняя Сводными таблицами, ВПР)?
Мне удобно это увидеть в виде битовой маски «0110», что будет означать, что конкретное значение есть только в списке 2 и списке 3.
Какими формулами это можно сделать в Excel/Calc?
(файл-пример см. внизу)
а) В колонку «C» вставляете первый список, в «D» второй, в «E» третий, «F» четвёртый.
б) В колонку «B» вставляете все списки один за другим.
в) В первой строке прописываете заголовки.
г) В ячейку «A2» вставляете формулу:
=СЧЁТЕСЛИ(C:C; B2) & СЧЁТЕСЛИ(D:D; B2) & СЧЁТЕСЛИ(E:E; B2) & СЧЁТЕСЛИ(F:F; B2)
или
=COUNTIF(C:C; B2) & COUNTIF(D:D; B2) & COUNTIF(E:E; B2) & COUNTIF(F:F; B2)
д) И, наконец, дважды щелкаете по правому нижнему углу ячейки «A2» (для автозаполнения).
Готово. С помощью битовой маски получаем понимание повторов.
Например, «0111» означает, что конкретный email/фрукт/показатель из колонки «B» повторятся во всех четырёх списках, кроме первого. «1000» означает, что значение только в первом списке.
ДОПОЛНИТЕЛЬНО-1: Если видите «0311», то можно понять, что во втором списке ещё и внутри списка дубликаты.
ДОПОЛНИТЕЛЬНО-2: Если видите «0000», значит явно закралась ошибка: в общем списке есть значение, которого нет ни в одном исходном списке.
Другой интересный способ — через условные веса.
Например, у нас аналогично четыре списка. Берём только одну колонку, куда засовываем значения вниз, допустим, в колонку «A» (или в textarea, если нет офисного пакета, но есть браузер).
Последний список копируем и вставляем 1 раз,
предпоследний список ниже вставляем 2 раза,
второй список копипастим 4 раза,
первый список копируем и вставляем вниз уже 8 раз подряд.
В общем виде подход для весов при N списках у нас идёт через удвоение 2^(N-1) (напр., при четырёх списках =2^(4-1)=2^3=8 "вес самого большого"), а возможных пересечений получается как 2^(N-1)*2-1 (напр., при четырёх списках =2^(4-1)*2-1=8*2-1=15 "непустых пересечений").
Дальше считаем повторы значений.
Полотно данных можно вставить, например, сюда: https://www.somacon.com/p568.php (если беспокоит приватность данных, скачайте страницу через CTRL+S и отключите Интернет, оно сработает локально!) (а можете использовать другой или самописный инструмент).
При четырёх списках каждое значение будет иметь число от «1» до «15».
Допустим, вы видите число «6». Удивительно, но если вы переведёте это в двоичную систему, то получите «0110» (или «110»). И это и будет значить, что это значение есть во втором и третьем списке, но нет ни в первом, ни в четвёртом!
«1» будет означать «0001» (или «1»), то есть значение имеется лишь в последнем списке,
«8» будет означать «1000», то есть лишь в первом списке,
«15» будет означать «1111», то есть значение имеется во всех списках!
СПРАВОЧНО-1: Держите двоичные числа с 0 до 31 (для пяти списков): 0, 1, 10, 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111, 10000, 10001, 10010, 10011, 10100, 10101, 10110, 10111, 11000, 11001, 11010, 11011, 11100, 11101, 11110, 11111. Дальше логика счёта такая же!
СПРАВОЧНО-2: В Excel/Calc переход туда и обратно осуществляется с помощью формул «ДВ.В.ДЕС» («BIN2DEC») и «ДЕС.В.ДВ» («DEC2BIN»).
Есть два сюжета.
> Во-первых, вы можете захотеть избежать ненаглядной конкатенации, то есть ненаглядного объединения текстовых строк,
когда у вас в одном списке оказалось десять и больше повторов.
Тогда формулу в ячейке «A2» можно сделать с пробелами, чтобы получить вид вроде «0 12 1 1»:
=СЧЁТЕСЛИ(C:C; B2) &" "& СЧЁТЕСЛИ(D:D; B2) &" "& СЧЁТЕСЛИ(E:E; B2) &" "& СЧЁТЕСЛИ(F:F; B2)
или
=COUNTIF(C:C; B2) &" "& COUNTIF(D:D; B2) &" "& COUNTIF(E:E; B2) &" "& COUNTIF(F:F; B2)
> Во-вторых, вы можете захотеть иметь только нули и единицы (если вам важно сохранять двоичную систему и вы не пытаетесь смотреть на повторы в самих списках):
=--(СЧЁТЕСЛИ(C:C; B2)>0) & --(СЧЁТЕСЛИ(D:D; B2)>0) & --(СЧЁТЕСЛИ(E:E; B2)>0) & --(СЧЁТЕСЛИ(F:F; B2)>0)
или
=--(COUNTIF(C:C; B2)>0) & --(COUNTIF(D:D; B2)>0) & --(COUNTIF(E:E; B2)>0) & --(COUNTIF(F:F; B2)>0)
Тут двойной минус перед скобкой превращает ИСТИНА (TRUE) в 1, а ЛОЖЬ (FALSE) в 0.
Если же оставляете анализ повторов внутри каждого списка, что бывает полезно, то с помощью фильтров/регулярных выражений типа «[2-9]» или вопросительного знака можно отыскивать значения больше единицы, но сюжет фильтров — отдельная крупная тема, без которой
при сравнении повторов любого количества списков
вполне можно обойтись!
Таким образом, здесь мы рассмотрели,
как удобно находить пересечения между несколькими заданными списками
и снизить вероятность ошибок/пропусков при их анализе.
> ПРИЛОЖЕНИЕ: Ссылка на файл (.xlsx)
Делитесь своими полезными советами!
Всем доброго дня. Сегодня хочу предложить вашему вниманию решение одной реальной задачи, которую мне прислала слушательница. Сразу отмечу, что похожие вопросы были и ранее. Поэтому решил аж целую статью накатать по этому поводу :)
Примечание: целью данной статьи ни в коем не является высмеивание людей, которые по тем или иным причинам пишут огромные формулы. Я лишь хочу показать, как важно знать различные мелкие нюансы, чтобы не усложнять себе жизнь на ровном месте.
Лень читать? Вот видео
Если не все, то наверняка многие сталкивались когда-нибудь с чем-то похожим:
Открываешь ячейку, а там… формула длиной в три экрана, собранная из костылей, велосипедов и какой-то матери. Если вы думаете, что это я специально написал в горячечном бреду, то нет. Самое забавное, что ЭТО даже как-то работало. И так было. Пока не появились они - счастливые обладатели компьютеров Apple. У них почему-то это не работало. Но это было не самое важное (не в обиду пользователям Apple). Куда важнее было оптимизировать формулу до адекватных размеров. Именно с таким вопросом ко мне и обратились. И сейчас я хочу представить вашему вниманию алгоритм решения похожих задач.
СПОЙЛЕР: задача была решена.
Прежде чем досконально разбираться в самой формуле (если честно, я этого так и не сделал), мне нужно было понять, какую вообще цель мы преследуем. Всё оказалось очень просто. Формула должна была решать тривиальную задачу: брать стоимость товара в долларах и переводить её в рубли по курсу ЦБ на определенную дату отгрузки. Казалось бы, обычный ВПР (VLOOKUP). Но автор исходника столкнулся с проблемой: курс есть на рабочие дни. На субботу и воскресенье банк его не выкатывает — нужно брать значение за пятницу. Чтобы это обойти, в формулу зашили кучу условий ЕСЛИ (IF), текстовые функции СЦЕПИТЬ (CONCATENATE), вытаскивание по отдельности дней, месяцев и годов... В общем, получился кошмар, который к тому же не работал на MacOS. Скорее всего, из-за разных стандартов в системах. Конкретную причину я не выяснял, так как после того, как отправил свой вариант, слушательница написала, что теперь всё работает даже на маках.
После того, как наметили цель, нужно понять, что нам поможет в достижении этой цели. Так, данные нужно подтянуть из одной таблицы в другую. Всё просто: ВПР (VLOOKUP). Движемся дальше.
И вот теперь переходим к самому интересному. Если задача такая простая, почему формула-то такая сложная?! Предлагаю вам взглянуть на таблицу с датами и попробовать самим понять, что с ними не так:
Посмотрели? Поняли? Кто понял, тот молодец, кто не понял, но продолжит читать, тот тоже молодец.
А царь-то даты-то ненастоящие! Выровнены по левому краю. Значит, это текст. И нельзя с ними работать, как с нормальными датами. Именно по этой причине формула и была такой страшной. Excel не умеет сопоставлять "правильную" дату из вашего отчета с текстовой строкой "13.07.2026". Автор извлекал по отдельности день, месяц, год. Далее с помощью функции ТЕКСТ(FORMAT) преобразовывал всё это в дату, и только потом сравнивал с датой в основной таблице. Вот этот кусок:
Решение очевидное: преобразовать текстовые даты в корректные даты. Тут стоит отметить, что нельзя это сделать простым изменением формата. Нельзя и всё тут. Далее те самые 5 стадий: отрицание, гнев, торг, депрессия, принятие. И теперь решение. В общем, есть безумно простой способ сделать это. Выделяем столбец, нажимаем Ctrl + H (Поиск и замена). В поле "Найти" пишем точку "." и в поле «Заменить на» пишем тоже точку ".". Жмем "Заменить все". Excel принудительно перезапишет ячейки, поймет, что это числа, и выровняет их по правому краю. Даты вылечены! Если в датах у вас дефисы или слэшы (/), то заменяйте их.
Теперь, когда даты стали датами, выбрасываем 90% старой формулы. Нам нужен ВПР. Но как заставить его автоматически брать курс за пятницу, если дата отгрузки выпала на субботу или воскресенье?
Все привыкли писать в конце ВПР ноль (0 или ЛОЖЬ), требуя точного совпадения. Но если мы поставим туда 1 или ИСТИНА, включится приблизительное совпадение.
Как это работает: если Excel не находит в таблице точную дату (например, субботу), он автоматически берет ближайшее меньшее значение. А ближайшим меньшим значением для субботы и воскресенья в календаре как раз и будет пятница!
!!! Важнейший нюанс !!!: чтобы этот трюк сработал, таблица с курсами валют ОБЯЗАТЕЛЬНО должна быть отсортирована по возрастанию (от старых дат к новым). Иначе ВПР сойдет с ума.
О чудо: огромная простыня текста превратилась в изящное:
Если у вас Excel 2021 года или свежее, можно использовать преемника — функцию ПРОСМОТРX (XLOOKUP). Она еще круче, потому что ей плевать на сортировку. Даже если даты в базе идут в полном хаосе, вы просто выставляете в пятом аргументе режим сопоставления -1 (точное совпадение или следующее меньшее). И всё работает идеально.
Что делать, если вам всё-таки нужно разобраться в чужой сложной формуле, а она выдает ошибку? Не пытайтесь расшифровать её глазами.
В Excel есть встроенный отладчик. Встаньте на ячейку со страшной формулой, перейдите на вкладку "Формулы" - группа "Зависимости формул" - кнопка "Вычислить формулу" (иконка с лупой и fx).
Excel откроет окно, в котором можно посмотреть, что происходит в формуле. Нажимая кнопку "Вычислить", вы будете видеть, как постепенно, шаг за шагом, считаются внутренние функции. Вы сразу (или не сразу, если формула сложно-огромная) поймете, на каком именно этапе и почему формула спотыкается и выдает ошибку.
У самурая нет цели, есть только путь — но в Excel этот подход не работает. Прежде чем писать гигантские формулы:
Приведите данные к правильному формату.
Определитесь с целью.
Подберите инструменты и изучите их.
Стоит отметить, что сократить формулу можно не всегда. Порой логика сложная и формула должна быть соответствующей. Тут уже ничего не попишешь. Либо смотреть в сторону Power Query, Pivot или VBA.
На этом, пожалуй, всё. Спасибо всем, кто дочитал до конца. Надеюсь, было полезно. В комментариях делитесь своими формулами-монстрами. Если статья "зайдёт", то, думаю, будет ещё несколько похожих, так как за время преподавания уже накопился определённый материал.
Когда мы разрабатываем систему, чаще всего тестируем её на небольшом объёме данных: несколько десятков или сотен записей. Но в реальной эксплуатации база может содержать миллионы строк, а одновременно системой могут пользоваться тысячи пользователей.
Именно поэтому перед вводом системы в эксплуатацию проводят нагрузочное тестирование.
В канале Аналитика FM я публикую реальные запросы SQL с разбором логики. Обсуждаем продуктовые метрики и как правильно строить аналитику данных.
Канал веду с нуля подписчиков.
Подписывайся, если тоже хочешь вникнуть в прекрасный мир аналитики.
Нагрузочное тестирование - это проверка работы системы под нагрузкой, максимально приближенной к реальной.
Его цель - ответить на вопросы:
Сколько пользователей одновременно выдержит система?
Как быстро будут выполняться запросы?
Как изменится производительность при увеличении объёма данных?
Не начнёт ли база данных работать значительно медленнее?
Не возникнут ли ошибки из-за нехватки памяти, места во временном табличном пространстве или перегрузки процессора?
Например, запрос, который за 0,1 секунды обрабатывает 100 строк, может выполняться несколько минут при таблице в 100 миллионов записей.
Поэтому проверять производительность необходимо именно на объёмах, близких к реальным.
Проверяется работа системы при обычной ожидаемой нагрузке.
Например:
одновременно работают 500 пользователей;
таблица содержит 10 миллионов записей.
На систему специально подают нагрузку выше расчётной.
Цель - определить предел её возможностей и понять, как она поведёт себя при перегрузке.
Проверяется влияние количества данных на производительность.
Например:
запрос работает с таблицей из 100 тыс. строк;
затем с 10 млн;
затем со 100 млн.
Система работает под постоянной нагрузкой несколько часов или даже суток.
Проверяют, не возникает ли утечек памяти и деградации производительности.
Самый простой способ - сгенерировать тестовые записи прямо средствами Oracle.
Например:
SELECT 'ООО Ромашка ' || LEVEL AS name,
7700000000 + LEVEL AS inn,
1027700000000 + LEVEL AS ogrn
FROM dual
CONNECT BY LEVEL <= 1000000;
Этот запрос создаст 1 миллион строк без использования каких-либо таблиц.
И так вы сможете подготовить базу с наполненными данными для тестирования нагрузки.
Иногда такого подхода не хватает, и данные должны быть консистентными, иметь логическую зависимость от других параметров. Но это уже более глубокая семантика нагрузочного тестирования.
А мы с вами начинаем познавать увлекательный мир аналитики и данных.
Разбор скрипта проведем в канале Аналитика FM.
Подписывайся, чтобы узнавать техническую сторону работы аналитика.
Генерация счетов-фактур — одна из самых распространённых задач в бизнес-приложениях. Будь то разработка ERP-системы, платформы электронной коммерции или внутреннего инструмента для выставления счетов, ручное создание счетов быстро становится неэффективным по мере роста числа клиентов.
Распространённый подход — разрабатывать счета в Excel, программно заполнять их данными, а затем экспортировать в PDF-файлы для распространения. Это сочетает гибкость шаблонов Excel с переносимостью и профессиональным видом PDF-документов.
В этой статье вы узнаете, как построить автоматизированный процесс создания счетов с помощью библиотеки Free Spire.XLS для Python. Мы возьмём шаблон счёта в Excel, заполним его информацией о клиенте и товарах, а затем экспортируем готовый счёт напрямую в PDF.
Многие разработчики пытаются генерировать счета непосредственно в PDF. Хотя это работает, часто требует построения макетов, форматирования таблиц, позиционирования текста и расчёта итогов в коде.
Шаблоны Excel имеют ряд преимуществ:
Просты в изменении для бизнес-пользователей
Встроенная поддержка формул и вычислений
Привычная среда проектирования
Не нужно жёстко прописывать макеты в коде
Простой экспорт в PDF
Вместо того чтобы воссоздавать макет счёта в коде, вы можете позволить Excel заниматься форматированием, в то время как ваше приложение сосредоточится на предоставлении данных.
Процесс выглядит так:
Данные счёта
↓
Шаблон Excel
↓
Заполнение ячеек
↓
Пересчёт формул
↓
Экспорт в PDF
Наш шаблон счёта содержит три раздела:
Верхняя часть включает информацию о компании и реквизиты счёта.
Эти ячейки будут заполняться программно.
Раздел позиций начинается со строки 16 и реализован как таблица Excel .
Этот выбор важен, поскольку таблицы Excel предоставляют несколько встроенных возможностей:
Автоматическое чередование цветов строк
Автоматическое распространение формул
Динамическое расширение таблицы
Упрощённое обслуживание
Например:
Шаблон уже содержит формулы для расчёта итогов по строкам.
Нижний раздел содержит формулы для:
Промежуточного итога
Налога
Общего итога
Вот как выглядит мой шаблон:
Установите библиотеку с помощью pip:
pip install spire.xls.free
Сначала загрузите шаблон Excel в книгу.
from spire.xls import *
from spire.xls.common import *
workbook = Workbook()
workbook.LoadFromFile("InvoiceTemplate.xlsx")
sheet = workbook.Worksheets[0]
На этом этапе всё форматирование, формулы и определения таблиц из шаблона доступны.
В реальных приложениях данные счёта обычно поступают из базы данных, API или ERP-системы.
В этом примере мы сохраним данные в словаре Python.
invoice = {
"company_name": "ABC Corporation",
"address_1": "123 Main Street",
"address_2": "New York, NY 10001",
"phone": "+1 (555) 123-4567",
"invoice_number": "INV-2026-001",
"customer_id": "CUST-1001",
"items": [
{
"qty": 2,
"description": "Laptop Computer",
"unit_price": 899.00
},
{
"qty": 1,
"description": "Wireless Mouse",
"unit_price": 29.99
},
{
"qty": 3,
"description": "USB-C Cable",
"unit_price": 12.50
}
]
}
Эта структура очень похожа на данные, возвращаемые многими бизнес-системами.
Далее заполним верхнюю часть счёта.
sheet.Range["C7"].Text = invoice["company_name"]
sheet.Range["C8"].Text = invoice["address_1"]
sheet.Range["C9"].Text = invoice["address_2"]
sheet.Range["C10"].Text = invoice["phone"]
sheet.Range["E8"].Text = invoice["invoice_number"]
sheet.Range["E9"].Text = invoice["customer_id"]
Эти значения заменяют заполнители, определённые в шаблоне.
Таблица позиций начинается со строки 16.
Мы можем записать каждую позицию в рабочий лист с помощью простого цикла.
start_row = 16
for index, item in enumerate(invoice["items"]):
row = start_row + index
sheet.Range[f"B{row}"].NumberValue = item["qty"]
sheet.Range[f"C{row}"].Text = item["description"]
sheet.Range[f"D{row}"].NumberValue = item["unit_price"]
Поскольку в шаблоне уже есть формулы для столбца «Line Total», нет необходимости вычислять суммы в коде.
Excel выполняет вычисления автоматически.
Одна из самых больших проблем при генерации счетов — обработка переменного количества товаров.
Традиционные шаблоны часто требуют от разработчиков:
Вручную копировать формулы
Дублировать форматирование
Пересчитывать диапазоны
Обновлять итоги
Таблицы Excel устраняют большую часть этой сложности.
При вставке новых строк:
Чередование цветов строк сохраняется
Формулы автоматически распространяются на новые строки
Ссылки на таблицу обновляются автоматически
Итоги продолжают работать корректно
В результате приложению нужно только сосредоточиться на вставке данных.
Такое разделение обязанностей делает код гораздо чище и проще в обслуживании.
Наш шаблон резервирует шесть строк для товаров.
Если счёт содержит более шести позиций, можно динамически добавить дополнительные строки.
base_rows = 6
if len(invoice["items"]) > base_rows:
sheet.InsertRow(
22,
len(invoice["items"]) - base_rows
)
Поскольку список товаров реализован как таблица Excel, новые вставленные строки автоматически наследуют форматирование и формулы таблицы.
Никакого дополнительного кода для стилизации не требуется.
Перед экспортом пересчитайте все формулы в книге.
workbook.CalculateAllValue()
Это гарантирует, что итоги по строкам, промежуточные итоги, налоги и общие итоги будут отражать актуальные данные.
Перед экспортом счёта в PDF часто стоит настроить параметры страницы рабочего листа.
Без правильной конфигурации в сгенерированном PDF могут быть большие поля, избыточные отступы или содержимое, неоправданно уменьшенное в масштабе.
Следующие настройки помогают максимально использовать полезную площадь страницы и обеспечить чистое отображение счёта.
sheet.PageSetup.LeftMargin = 0.0
sheet.PageSetup.RightMargin = 0.0
sheet.PageSetup.TopMargin = 0.0
sheet.PageSetup.BottomMargin = 0.0
# Вместить рабочий лист на одну страницу
workbook.ConverterSetting.SheetFitToPage = True
Эти настройки:
Убирают ненужные поля
Максимизируют доступное пространство
Улучшают читаемость
Дают более профессиональный вид PDF
Если счёт может содержать много товаров и занимать несколько страниц, размещение всего листа на одной странице обычно нежелательно, потому что содержимое становится слишком мелким.
В этом случае настройте лист на соответствие ширине страницы, разрешив неограниченную высоту.
sheet.PageSetup.FitToPagesWide = 1
sheet.PageSetup.FitToPagesTall = 0
Это указывает Excel:
Уместить счёт в пределах ширины одной страницы
Автоматически создавать дополнительные страницы по вертикали при необходимости
В результате длинные счета остаются читаемыми, сохраняя исходное форматирование.
Наконец, сохраните книгу как PDF-документ.
workbook.SaveToFile(
"Invoice.pdf",
FileFormat.PDF
)
Поскольку макет листа уже оптимизирован, экспортированный PDF сохраняет предполагаемый внешний вид счёта.
Сгенерированная PDF-счет выглядит так:
from spire.xls import Workbook, FileFormat
# Создание книги
workbook = Workbook()
workbook.LoadFromFile(r"C:\Users\Administrator\Desktop\invoice-template.xlsx")
# Получение рабочего листа
sheet = workbook.Worksheets[0]
# ==========================================
# Данные счёта
# ==========================================
invoice = {
"company_name": "ABC Corporation",
"address_1": "123 Main Street",
"address_2": "New York, NY 10001",
"phone": "+1 (555) 123-4567",
"invoice_number": "INV-2026-001",
"customer_id": "CUST-1001",
"items": [
{
"qty": 2,
"description": "Laptop Computer",
"unit_price": 899.00
},
{
"qty": 1,
"description": "Wireless Mouse",
"unit_price": 29.99
},
{
"qty": 3,
"description": "USB-C Cable",
"unit_price": 12.50
}
]
}
# ==========================================
# Заполнение информации о счёте
# ==========================================
# C7-C10
sheet.Range["C7"].Text = invoice["company_name"]
sheet.Range["C8"].Text = invoice["address_1"]
sheet.Range["C9"].Text = invoice["address_2"]
sheet.Range["C10"].Text = invoice["phone"]
# E8-E9
sheet.Range["E8"].Text = invoice["invoice_number"]
sheet.Range["E9"].Text = invoice["customer_id"]
# ==========================================
# Заполнение позиций счёта
# ==========================================
start_row = 16
for index, item in enumerate(invoice["items"]):
row = start_row + index
sheet.Range[f"B{row}"].NumberValue = item["qty"]
sheet.Range[f"C{row}"].Text = item["description"]
sheet.Range[f"D{row}"].NumberValue = item["unit_price"]
# ==========================================
# Пересчёт формул
# ==========================================
workbook.CalculateAllValue()
# ==========================================
# Экспорт в PDF
# ==========================================
sheet.PageSetup.LeftMargin = 0.0
sheet.PageSetup.RightMargin = 0.0
sheet.PageSetup.TopMargin = 0.0
sheet.PageSetup.BottomMargin = 0.0
# Вместить лист на одну страницу
workbook.ConverterSetting.SheetFitToPage = True
# Для длинного счёта, превышающего одну страницу, установите FitToPagesTall = 0,
# чтобы разрешить размещение на нескольких страницах по вертикали
# sheet.PageSetup.FitToPagesWide = 1
# sheet.PageSetup.FitToPagesTall = 0
workbook.SaveToFile(
"Invoice.pdf",
FileFormat.PDF
)
workbook.Dispose()
Использование Excel в качестве движка для шаблонов счетов может значительно упростить генерацию счетов. Храня макеты, формулы и форматирование в электронной таблице, разработчики могут сосредоточиться на предоставлении данных, а не на управлении деталями представления.
Сочетание шаблона Excel с Free Spire.XLS для Python позволяет автоматизировать весь процесс — от заполнения данных счёта до создания профессиональных PDF-документов — с удивительно небольшим количеством кода.
Когда раздел позиций счёта реализован как таблица Excel, решение становится ещё более поддерживаемым. Форматирование, формулы и расширение таблицы обрабатываются автоматически, что упрощает поддержку счетов любого размера, сохраняя вашу кодовую базу чистой и простой.