Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

312
Views
Cómo recortar (recortar) el espacio en blanco inferior de un documento PDF, en la memoria

Estoy usando wkhtmltopdf para representar un documento HTML (con plantilla de Django) en un archivo PDF de una sola página. Me gustaría renderizarlo inmediatamente con la altura correcta (que no he podido hacer hasta ahora) o renderizarlo incorrectamente y recortarlo. Estoy usando Python.

Intento tipo 1:

  • wkhtmltopdf convierte en un PDF de una sola página muy, muy largo con mucho espacio adicional usando --page-height
  • Utilice pdfCropMargins para recortar: crop(["-p4", "100", "0", "100", "100", "-a4", "0", "-28", "0", "0", "input.pdf"])

El PDF se representa perfectamente con 28 unidades de margen en la parte inferior, pero tuve que usar el sistema de archivos para ejecutar el comando de crop . Parece que la herramienta espera un archivo de entrada y un archivo de salida, y también crea archivos temporales a la mitad. Así que no puedo usarlo.

Intento tipo 2:

  • wkhtmltopdf renderizar a PDF de varias páginas con parámetros predeterminados
  • Use PyPDF4 (o PyPDF2 ) para leer el archivo y combinar páginas en una sola página larga

El PDF se muestra muy bien en la mayoría de los casos, sin embargo, a veces se pueden ver muchos espacios en blanco adicionales en la parte inferior si por casualidad la última página del PDF tenía muy poco contenido.

Escenario ideal:

El escenario ideal implicaría una función que tome HTML y lo convierta en un PDF de una sola página con la cantidad esperada de espacio en blanco en la parte inferior. Estaría feliz de renderizar el PDF usando wkhtmltopdf , ya que devuelve bytes y luego procesar estos bytes para eliminar cualquier espacio en blanco adicional. Pero no quiero involucrar al sistema de archivos en esto, sino que quiero realizar todas las operaciones en la memoria. ¿Quizás de alguna manera pueda inspeccionar el PDF directamente y eliminar el espacio en blanco manualmente, o hacer algo de magia HTML para determinar la altura de procesamiento de antemano?

Que estoy haciendo ahora:

Tenga en cuenta que pdfkit es un contenedor wkhtmltopdf

 # This is not a valid HTML (includes Django-specific stuff) template: Template = get_template("some-django-template.html") # This is now valid HTML rendered = template.render({ "foo": "bar", }) # This first renders PDF from HTML normally (multiple pages) # Then counts how many pages were created and determines the required single-page height # Then renders a single-page PDF from HTML using the page height and width arguments return pdfkit.from_string(rendered, options={ "page-height": f"{297 * PdfFileReader(BytesIO(pdfkit.from_string(rendered))).getNumPages()}mm", "page-width": "210mm" })

Es equivalente a Attempt type 2 , excepto que no uso PyDPF4 aquí para unir las páginas, sino que renderizo de nuevo con wkhtmltopdf usando la altura de página precalculada.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Puede haber mejores maneras de hacer esto, pero 3 días después de una recompensa sin respuestas, esto al menos funciona. Supongo que puede recortar el PDF usted mismo, y todo lo que hago aquí es determinar qué tan abajo en la última página todavía tiene contenido. Si esa suposición es incorrecta, probablemente podría descubrir cómo recortar el PDF. O, de lo contrario, simplemente recorte la imagen (fácil en Pillow) y luego conviértala a PDF. Además, si tiene un PDF grande, es posible que deba calcular qué tan abajo termina el texto en todo el PDF. Solo estoy averiguando qué tan abajo en la última página termina el contenido. Pero convertir de uno a otro es como un simple problema aritmético.

Código probado:

 import pdfkit from PyPDF2 import PdfFileReader from io import BytesIO # This library isn't named fitz on pypi, # obtain this library with `pip install PyMuPDF==1.19.4` import fitz # `pip install Pillow==8.3.1` from PIL import Image import numpy as np # However you arrive at valid HTML, it makes no difference to the solution. rendered = "<html><head></head><body><h3>Hello World</h3><p>hello</p></body></html>" # This first renders PDF from HTML normally (multiple pages) # Then counts how many pages were created and determines the required single-page height # Then renders a single-page PDF from HTML using the page height and width arguments pdf_bytes = pdfkit.from_string(rendered, options={ "page-height": f"{297 * PdfFileReader(BytesIO(pdfkit.from_string(rendered))).getNumPages()}mm", "page-width": "210mm" }) # convert the pdf into an image. pdf = fitz.open(stream=pdf_bytes, filetype="pdf") last_page = pdf[pdf.pageCount-1] matrix = fitz.Matrix(1, 1) image_pixels = last_page.get_pixmap(matrix=matrix, colorspace="GRAY") image = Image.frombytes("L", [image_pixels.width, image_pixels.height], image_pixels.samples) #Uncomment if you want to see. #image.show() # Now figure out where the end of the text is: # First binarize. This might not be the most efficient way to do this. # But it's how I do it. THRESHOLD = 100 # I wrote this code ages ago and don't remember the details but # basically, we treat every pixel > 100 as a white pixel, # We convert the result to a true/false matrix # And then invert that. # The upshot is that, at the end, a value of "True" # in the matrix will represent a black pixel in that location. binary_matrix = np.logical_not(image.point( lambda p: 255 if p > THRESHOLD else 0 ).convert("1")) # Now find last white row, starting at the bottom row_count, column_count = binary_matrix.shape last_row = 0 for i, row in enumerate(reversed(binary_matrix)): if any(row): last_row = i break else: continue percentage_from_top = (1 - last_row / row_count) * 100 print(percentage_from_top) # Now you know where the page ends. # Go back and crop the PDF accordingly.
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!