Completando formularios PDF de forma automática

Gustavo Orrillo
- 02/16/2021 - 1 min. de lectura


Muchas veces nos encontramos con la necesidad de permitir al usuario descargar formularios PDFs ya previamente completados con información del objeto con el cual estemos trabajando. Ahí se preguntarán... por que no lo hacemos con Q-Web? Porque hay veces que el cliente espera que un diseñador le prepare el PDF que es más bonito que un reporte creado por un programador (en eso,le doy la razón al cliente). La idea del formulario previamente completado es alivianar la tarea administrativa del empleado.

Bien, como podemos hacer eso? Hay dos maneras, y las dos comparten la misma librería de python (fdfgen). La primer manera es usar el módulo report_fillpdf, el cual te permite generar un reporte de un objeto como si fuese un reporte q-web. Con la salvedad que es el formulario pdf completado con los datos del objeto. El problema que tiene este enfoque es, el módulo está para versión 11 pero no para versiones posteriores. O sea deberíamos migrarlo. Es por eso que desistí de usarlo.

La otra manera es usando la librería fdfgen. La idea es; en un campo binario guardar el PDF ya completado con los datos del objeto. Y eso lo podemos hacer durante (a modo de ejemplo, en este caso imprimiendo los datos de un partner) el create del objeto. Esto extiende la funcionalidad explicada en la página de fdfgen:

from fdfgen import forge_fdf
import subprocess
@api.model
def create(self, vals):
    res = super(ResPartner, self).create(vals)
    fields = [('name', res.name), ('telephone', res.phone)]
    fdf = forge_fdf("",fields,[],[],[])
    original_pdf = < nombre del archivo pdf > 
    with open("data.fdf", "wb") as fdf_file:
        fdf_file.write(fdf)
        subprocess.run(['pdftk',original_pdf,'fill_form',out_fdf_filename,'output','out.pdf','flatten'])
    with open("out.fdf", "rb") as pdf_file:
        file_content = pdf_file.read()
        pdf_file.close()
        vals = {'text_file':  base64.b64encode(file_content)}
        res.write(vals)
    return res

Bueno, fue algo que aprendí esta mañana que quise compartir.


Acerca de:

Gustavo Orrillo

Passionate about programming, he has implemented Odoo for different types of businesses since 2010. In Moldeo Interactive he is a founding Partner and Programmer; In addition to writing on the Blog about different topics related to the developments he makes.