Catalogue creation with Page-Design

I have designed a catalogue with Page Design. The inforation of a product fits in 1/5 of a letter sized page. When printing, it prints 1 product per page instead of placing 4 or 5 products per page. I am using Setable cloud.

Your Setup:

  • SeaTable Cloud, Dedicated or Self-hosted?
  • SeaTable Version (only necessary for self-hosted):
    You can find your SeaTable Server version at https://your-server-url/server-info

Describe the Problem/Error/Question:

Please describe your issue as precise as possible. If helpful, you can also provide:

  • Screenshots
  • Diagrams with Excalidraw
  • Base structure details using this script.

Error Messages:

If there are any error messages shown in the browser console, please include them for better readability by wrapping them in a code block.

Example of a code block for error messages

Hi @Renel, and welcome to the SeaTable forum!
Unfortunately, the Page Design isn’t currently capable of combining your pages depending on their size in a page.
Here is a “not-so-simple-but-still-working” workaround I found:

  • in your Page Design plugin, select a custom size for your page and set the appropriate width and height.
  • use the print / all records in view function to get one single PDF containing one single record per page. Don’t forget to set the same custom format as you did for your page!
  • upload this PDF in SeaTable in a File column. In the considered table, you’ll also need another File column for the combined PDF
  • create a Python script and run it on the considered row. Here is the code, with few explanations:
from math import floor, ceil
from pypdf import PaperSize, PdfReader, PdfWriter, Transformation
from seatable_api import Base,context

base = Base(context.api_token,context.server_url)
base.auth()

TABLE_NAME = 'Catalogue'
ONE_RECORD_PER_PAGE_PDF_COLUMN = 'File'
COMBINED_PDF_COLUMN = 'Res'

CUSTOM_WIDTH = 395
CUSTOM_HEIGHT = 280

OUTPUT_FORMAT_WIDTH = PaperSize.A4.width
OUTPUT_FORMAT_HEIGHT = PaperSize.A4.height

# Read source file
base.download_file(context.current_row[ONE_RECORD_PER_PAGE_PDF_COLUMN][0]['url'],context.current_row[ONE_RECORD_PER_PAGE_PDF_COLUMN][0]['name'])
reader = PdfReader(context.current_row[ONE_RECORD_PER_PAGE_PDF_COLUMN][0]['name'])

number_of_items = len(reader.pages)

number_of_cols = floor(OUTPUT_FORMAT_WIDTH/CUSTOM_WIDTH)+1
number_of_rows = floor(OUTPUT_FORMAT_HEIGHT/CUSTOM_HEIGHT)+1

number_of_pages = ceil(number_of_items/(number_of_cols*number_of_rows))

print(f"{number_of_items} items > {number_of_pages} pages of {number_of_rows} x {number_of_cols}")

# Create a destination file, and add a blank page to it
writer = PdfWriter()

for y in range(number_of_pages):
  destpage = writer.add_blank_page(width=OUTPUT_FORMAT_WIDTH, height=OUTPUT_FORMAT_HEIGHT)
  page_idx = y*number_of_cols*number_of_rows
  for row in range(number_of_rows):
    for col in range(number_of_cols):
      if page_idx < number_of_items:
        destpage.merge_transformed_page(
          reader.pages[page_idx],
          Transformation().translate(
              col * reader.pages[page_idx].mediabox.width,
              OUTPUT_FORMAT_HEIGHT - (row+1) * reader.pages[page_idx].mediabox.height,
          ),
      )
      page_idx += 1

writer.write("output.pdf")
info_dict = base.upload_local_file("output.pdf", name=None, file_type='file', replace=True) 
base.update_row(TABLE_NAME, context.current_row['_id'], {COMBINED_PDF_COLUMN: [info_dict]})
    
print('Uploaded PDF file')

You’ll have to modify few variables at the beginning of the script:

  • TABLE_NAME: the table containing the PDF
  • ONE_RECORD_PER_PAGE_PDF_COLUMN: the column containing the initial (one record per page) PDF file
  • COMBINED_PDF_COLUMN: the column where you’ll store the resulting combined PDF
  • CUSTOM_WIDTH: the custom width you set in the Page Design plugin
  • CUSTOM_HEIGHT: the custom height you set in the Page Design plugin
  • OUTPUT_FORMAT_WIDTH: the width of the output PDF
  • OUTPUT_FORMAT_HEIGHT: the height of the output PDF

For those last two variables, the pypdf library offers variables for All Din-A paper sizes (as you can see, in this example I used the variables for A4 format : PaperSize.A4.width and PaperSize.A4.height. If you want to use an inch-based format, just multiply the size in inch by 72 (dpi).

Here are few tips to calculate an appropriate item format in Page Design (ready for an headache? :sweat_smile:). Your page size should ideally be a fraction of your output document but the Page Design plugin and the pypdf library don’t consider the same resolution, so you have to take that into account : pypdf works with a 72 dpi, whereas SeaTable Page Design plugin uses a 96 dpi. So for my example of an A4 document:

  • pypdf gives me PaperSize.A4.width = 595 (210 mm / 25.4 to get the width in inch * 72dpi - the resolution) and PaperSize.A4.height = 842 (297 mm / 25.4 to get the height in inch * 72 - the resolution)
  • to get the corresponding 96dpi-based size for the Page Design plugin, I’ll use the same formula but I’ll multiply by 96 instead of 72, so I now have ~ 793 x 1123
  • If I imagine having 2 columns x 4 rows of items on my A4 page (portrait orientation), the max size of my item will be 793/2 ≈ 396.5 (width) x 1123/2 ≈ 561, so I can choose I custom format something like 395 * 500

I realize that it’s really complex, but I hope this might still help you.

Bests,
Benjamin

Thank you Benjamin, I will try your suggestion.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.