Como imprimir una planilla Excel en Odoo con la librería XlsxWriter usando el módulo report_xlsx

2 de julio de 2023 por
Andres Dawidowicz
| Sin comentarios aún
 

El manejo que logra Odoo con la librería XlsxWriter es muy potente y poder generar planillas con la info de Odoo nos da una enorme gama de posibilidades para que nuestro sistema  ofrezca importantes ventajas sobre los listados que vienen en el core de Odoo.

Como ya nombramos en el blog para armar un Excel con el stock o para personalizar una IVA Ventas-Compras que cada contador tiene su forma es un elemento distintivo de lo que pueda ofrecer otro partner

Este es un ejemplo de un Excel hecho con Odoo con formatos, fórmulas, autofiltros, inmovilizador de paneles, etc. Y se podrían agregar gráficos, botones, formularios, etc.

Entonces, vamos a ver el código para ver como hacer un Excel.

Hay que tener instalada la aplicación report_xlsx y luego tenemos que tener en un archivo XML el código para agregar un reporte estilo XLSX con el modelo que vamos a usar. Esto va a agregar en el formulario del modelo un opción de imprimir el Excel

<odoo>
<report
id="account_vat_ledger_xlsx"
model="account.vat.ledger"
string="Print to XLSX"
report_type="xlsx"
name="l10n_ar_account_vat_ledger.account_vat_ledger_xlsx"
file="account_vat_ledger"
attachment_use="False"
/>

</odoo>

En el name tenemos el nombre de la función que va a armar el archivo en el modelo que pusimos en model

La función sería algo como esto, en donde les pongo unas cuantas funciones de lo poderosa de la herramienta

class AccountVatLedgerXlsxColumn(models.AbstractModel):
_name = 'report.l10n_ar_account_vat_ledger.vat_column_xlsx'
_inherit = 'report.report_xlsx.abstract'

def generate_xlsx_report(self, workbook, data, vat_ledger):
if vat_ledger.invoice_ids:
report_name = 'IVA Compras'
sheet = workbook.add_worksheet(report_name[:31])
money_format = workbook.add_format({'num_format': '$#,##0.00'})
total_format = workbook.add_format({'num_format': '$#,##0.00', 'bold': True,'bg_color':'#E3E2E4','border': True})
titulo = workbook.add_format({'font_size': 20, 'bold': True,'bg_color':'#E3E2E4','align': 'center','border': True})
bold = workbook.add_format({'bold': True,'bg_color':'#E3E2E4','align': 'center','border': True})
#sheet.write(1, 0, vat_ledger.display_name, bold)
sheet.merge_range(1,0,1,3, vat_ledger.display_name, titulo)
titles = ['Fecha','Tipo Comprobante','Nro Comprobante','Razón Social','CUIT','Responsabilidad AFIP',
'Neto gravado 21%','Neto gravado 10.5%','Neto gravado 27%',
'IVA 21%','IVA 10.5%','IVA 27%',
'PERC.IVA','No Gravado','Fac.C',
'Perc.IIBB','Total','PIB CABA','PIB BS AS']
for i,title in enumerate(titles):
sheet.write(3, i, title, bold)
row = 4
index = 0
sheet.set_column('A:A', 10) #fecha
sheet.set_column('B:B', 16) #tipo
sheet.set_column('C:C', 19) #número
sheet.set_column('D:D', 30) #razon social
sheet.set_column('E:E', 11) #cuit
sheet.set_column('F:F', 25) #cuit
sheet.set_column('G:L', 18) #Números grandes
sheet.set_column('G:L', 18) #Números grandes
sheet.set_column('M:P', 14) #Números chicos
sheet.set_column('Q:Q', 18) #Números grandes
sheet.set_column('R:S', 14) #Números chicos

for i,obj in enumerate(vat_ledger.invoice_ids):
# One sheet by partner
#if obj.qty_available < 1:
# continue
sheet.write(row + index, 0, obj.invoice_date.strftime("%Y-%m-%d"))
sheet.write(row + index, 1, obj.l10n_latam_document_type_id.display_name)
sheet.write(row + index, 2, obj.display_name)
sheet.write(row + index, 3, obj.partner_id.display_name)
sheet.write(row + index, 4, obj.partner_id.vat)
sheet.write(row + index, 5, obj.partner_id.l10n_ar_afip_responsibility_type_id.name)

sheet.write(row + index,6, 0.00,money_format)
sheet.write(row + index,7, 0.00,money_format)
sheet.write(row + index,8, 0.00,money_format)
sheet.write(row + index,9, 0.00,money_format)
sheet.write(row + index,10, 0.00,money_format)
sheet.write(row + index,11, 0.00,money_format)
sheet.write(row + index,12, 0.00,money_format)
sheet.write(row + index,13, 0.00,money_format)
sheet.write(row + index,14, 0.00,money_format)
sheet.write(row + index,15, 0.00,money_format)
sheet.write(row + index,16, 0.00,money_format)
sheet.write(row + index,17, 0.00,money_format)
sheet.write(row + index,18, 0.00,money_format)


vat_taxable_amount = 0.00
vat_exempt_base_amount = 0.00
per_iva = 0.00
per_iibb = 0.00
per_ibcaba = 0.00
per_ibarba = 0.00
for move_tax in obj.move_tax_ids:
if move_tax.tax_id.tax_group_id.tax_type == 'vat':
if move_tax.tax_id.amount != 0:
vat_taxable_amount += move_tax.base_amount
else:
vat_exempt_base_amount += move_tax.base_amount
if move_tax.tax_id.tax_group_id.tax_type == 'withholdings':
if move_tax.tax_id.tax_group_id.l10n_ar_tribute_afip_code in ['01','06']:
per_iva += move_tax.tax_amount
if move_tax.tax_id.tax_group_id.l10n_ar_tribute_afip_code in ['07']:
per_iibb += move_tax.tax_amount

busqueda_CABA = move_tax.tax_id.tax_group_id.name.find('CABA')
if busqueda_CABA !=-1:
per_ibcaba += move_tax.tax_amount

busqueda_ARBA = move_tax.tax_id.tax_group_id.name.find('ARBA')
if busqueda_ARBA !=-1:
per_ibarba += move_tax.tax_amount

sheet.write(row + index,12, per_iva,money_format)
sheet.write(row + index,13, vat_exempt_base_amount,money_format)
sheet.write(row + index,15, per_iibb,money_format)
sheet.write(row + index,17, per_ibcaba,money_format)
sheet.write(row + index,18, per_ibarba,money_format)

#sheet.write(row + index, 6, vat_taxable_amount,money_format)

for tax_line in obj.move_tax_ids:
if tax_line.tax_id.amount == 21:
sheet.write(row + index, 6, tax_line.base_amount,money_format)
sheet.write(row + index, 9, tax_line.tax_amount,money_format)
if tax_line.tax_id.amount == 10.5:
sheet.write(row + index, 7, tax_line.base_amount,money_format)
sheet.write(row + index, 10, tax_line.tax_amount,money_format)
if tax_line.tax_id.amount == 27:
sheet.write(row + index, 8, tax_line.base_amount,money_format)
sheet.write(row + index, 11, tax_line.tax_amount,money_format)


sheet.write(row + index, 16, obj.amount_total,money_format)
if obj.partner_id.l10n_ar_afip_responsibility_type_id.name.find('Monotributo') !=-1:
sheet.write(row + index, 14, obj.amount_total,money_format)

index += 1
sheet.write(row + index, 5, 'Totales',bold)
sheet.autofilter(row-1, 0, row, 18)
sheet.freeze_panes(4, 0) # Freeze the first row.
col_G = '=sum(G'+str(row+1)+':G'+str(row+index)+')'
col_H = '=sum(H'+str(row+1)+':H'+str(row+index)+')'
col_I = '=sum(I'+str(row+1)+':I'+str(row+index)+')'
col_J = '=sum(J'+str(row+1)+':J'+str(row+index)+')'
col_K = '=sum(K'+str(row+1)+':K'+str(row+index)+')'
col_L = '=sum(L'+str(row+1)+':L'+str(row+index)+')'
col_M = '=sum(M'+str(row+1)+':M'+str(row+index)+')'
col_N = '=sum(N'+str(row+1)+':N'+str(row+index)+')'
col_O = '=sum(O'+str(row+1)+':O'+str(row+index)+')'
col_P = '=sum(P'+str(row+1)+':P'+str(row+index)+')'
col_Q = '=sum(Q'+str(row+1)+':Q'+str(row+index)+')'
col_R = '=sum(R'+str(row+1)+':R'+str(row+index)+')'
col_S = '=sum(S'+str(row+1)+':S'+str(row+index)+')'

sheet.write(row + index, 6, col_G, total_format)
sheet.write(row + index, 7, col_H, total_format)
sheet.write(row + index, 8, col_I, total_format)
sheet.write(row + index, 9, col_J, total_format)
sheet.write(row + index, 10, col_K, total_format)
sheet.write(row + index, 11, col_L, total_format)
sheet.write(row + index, 12, col_M, total_format)
sheet.write(row + index, 13, col_N, total_format)
sheet.write(row + index, 14, col_O, total_format)
sheet.write(row + index, 15, col_P, total_format)
sheet.write(row + index, 16, col_Q, total_format)
sheet.write(row + index, 17, col_R, total_format)
sheet.write(row + index, 18, col_S, total_format)


En el ejemplo generamos distintos formatos, texto, con negrita, con formato numérico, tamaños y luego cuando insertamos un dato en una celda lo hacemos con uno de los formatos deseados, seteamos anchos de columnas, combinación de celdas, insertamos fórmulas, autofiltro, etc. Y al terminar el código se descarga el Excel a nuestro equipo.



Andres Dawidowicz 2 de julio de 2023
Compartir
Archivar
Identificarse dejar un comentario