#python #reportlab
#python #reportlab
Вопрос:
Я готовлю отчет в формате PDF со списком элементов, который по сути представляет собой длинную таблицу, некоторые ячейки которой заполнены данными, а некоторые пустые. Этот отчет будет распечатан, и пользователь заполнит пустые ячейки на бумаге. Она также добавит новые строки и заполнит новыми данными.
Итак, я предоставлю несколько (например, 3) пустых строк в виде таблицы для заполнения данными. Но если на странице еще осталось место, я бы хотел заполнить его пустыми строками.
Как я могу добавить столько строк, сколько поместится на последней странице?
Другой подход:
Возможно, такого поведения легче достичь при использовании абзаца с однострочной таблицей для каждой строки. Но мне нужно, чтобы первая строка повторялась на каждой странице (что легко в таблицах с repeatRows=1
).
Есть идеи?
Ответ №1:
Мне нужно будет восстановить часть моего кода, но, кажется, я припоминаю, что мне приходилось что-то делать, измеряя текущую позицию X / Y, вычисляя это с учетом того, какой запас я использовал, а затем определять, может ли поместиться больше информации или мне нужна новая страница. Мой проект заключался в переносе длинных блоков текста в word, что похоже, но не совсем аналогично. Вскоре я добавлю сюда некоторый код.
def newline(self, options, text = ''):
if getattr(self, 'lpp', None) == self.lines[self.pages]:
self.newpage()
if getattr(self, 'y', None) > self.h - self.bm * inch:
self.newpage()
В этом случае у меня были атрибуты для lpp (строк на страницу), которые, возможно, были установлены, поэтому я сначала проверил, существует ли это значение, и если да, то соответствую ли я количеству строк для текущей страницы. Если бы не было ограничения на общее количество строк на странице, тогда я проверил, какой была бы моя позиция Y и каково было нижнее поле. При необходимости исправьте страницу. Здесь кое-что упущено, но это общая идея.
def newline(self, options, text = ''):
if getattr(self, 'lpp', None) == self.lines[self.pages]:
self.newpage()
if getattr(self, 'y', None) > self.h - self.bm * inch:
self.newpage()
self.addLine()
self.putText(self.x, self.h - self.y, text)
def putText(self, x, y, text):
# If we actually place some text then we want to record that.
if len(text.strip()) > 0 and not self.hasText[self.pages]:
self.hasText[self.pages] = True
# Something here to handle word wrap.
if self.wrap:
lines = self._breakScan(text)
if len(lines) > 1:
self.c.drawString(x, y, lines[0])
self.newline('', ' '.join(lines[1:]))
elif lines:
self.c.drawString(x, y, lines[0])
else:
self.c.drawString(x, y, text)
Вот, self.c
мой холст. Я отслеживаю, сколько строк я поместил на странице, потому что бывают случаи, когда мы переназначаем документ, который может содержать разрывы страниц, все в нашей пользовательской разметке.
Комментарии:
1. Думаю, я понял идею. Является ли перевод строки методом Paragraph? Когда это вызывается?
2. @jammon — Извините, я мог бы объяснить свой подход немного подробнее. Self в данном случае является пользовательским классом. Он сопоставляет различные команды из пользовательского синтаксиса разметки с соответствующими вызовами api в reportlab. В их библиотеке, вероятно, нет
newline()
метода. Я добавлю некоторый дополнительный код для дальнейшей демонстрации.3. Большое вам спасибо. Я постараюсь разобраться в этом своим умом. Reportlab отлично подходит для начинающих, но наверняка есть ребра и задачи, решение которых далеко не очевидно.
4. @jammon — Без проблем. Рад помочь. Я обнаружил, что есть пара вещей, которые, вероятно, были бы более удобными при использовании их платной библиотеки, но, используя библиотеки с открытым исходным кодом, вы в конечном итоге кодируете в обход некоторых из их встроенных ограничений. Эта штука со строками на странице, безусловно, одна из них.
Ответ №2:
В зависимости от того, где заканчивается эта таблица в документе, быстрым и хакерским решением может быть просто вставить в таблицу достаточное количество строк, чтобы убедиться, что она заполняет страницу и переходит на следующую страницу. Затем, после создания документа, отрежьте последнюю страницу и создайте новый PDF, в котором не будет этой страницы.
Конечно, это работает, только если таблица находится в конце документа (или, если вы используете коммерческую версию ReportLab, вы могли бы сшивать PDF-файлы, в этом случае это не имело бы значения), и это немного некрасиво, как я уже сказал, но это выполняет свою работу..