В reportlab добавьте в длинную таблицу столько пустых строк, сколько поместится на последней странице

#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-файлы, в этом случае это не имело бы значения), и это немного некрасиво, как я уже сказал, но это выполняет свою работу..