Cómo crear un PDF a partir de un xml

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Paredes01
Usuário Nível 2
Usuário Nível 2
Mensagens: 54
Registrado em: 20 Mai 2012 11:22
Localização: Mérida, Yucatán, México

Cómo crear un PDF a partir de un xml

Mensagem por Paredes01 »

Buen día
Necesito crear un PDF a partir de un xml

Tengo que utilizar Harbour, hbxml, hbhpdf, hbzebra

En C:\hb32\include no encuentro hbhpdf.ch

En C:\hb32\contrib\hbhpdf\
encontre harupdf.ch

Este archivo lo renombre a hbhpdf.ch y lo copie a c:\hb32\include
(no se, si es lo correcto).

Versión de harbour:
Harbour Make (hbmk2) 3.2.0dev (r2026-01-09 16:42)
Copyright (c) 1999-present, Viktor Szakats
https://github.com/harbour/core/
Traducción (es): Guillermo Varona Silupú <gvaronas@gmail.com>

Harbour Build Info
---------------------------------------------------------------------------------------------
Version: Harbour 3.2.0dev (r2601091642)
Compiler: MinGW GNU C 7.3 (32-bit)
Platform: Windows 11 or newer 10.0.26200
PCode version: 0.3
ChangeLog last entry: 2026-01-09 17:42 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
ChangeLog ID: 186927c3a792d0c408b591155ef84b7b88e12c37
Built on: Jan 10 2026 05:07:50
Build options: (Clipper 5.3b) (Clipper 5.x undoc)
--------------------------------------------------------------------------------------------

Consulta de herramientas externas:
hbmk2 -find hbhpdf
hbhpdf.hbc (instalado):
__HBEXTERN__HBHPDF__()

hbmk2 -find hbzebra
hbzebra.hbc (instalado):
__HBEXTERN__HBZEBRA__()

hbmk2 -find hbmxml
hbmxml.hbc (instalado):
__HBEXTERN__HBMXML__()


Cómo debo incluir en mi archivo HBP las herramientas externas.
este es mi archivo HBP
*****************************************************************************
-oREP-PAGO
-inc

-w3 -es2

-mt
-compr=yes
-quiet
-lxhb
-lhbwin
-lhbct
-lhbnf
-lgrump
-lsuperlib
-lgtwvt
-lgtwvg
#-gui

PAGO-GEMI.prg
****************************************************************************

Cuando compilo, surgen estos errores:

hbmk2: Procesando opciones de entorno: -comp=mingw
Harbour 3.2.0dev (r2601091642)
Copyright (c) 1999-2025, https://harbour.github.io/
Compiling 'PAGO-GEMI.prg'...
Lines 1267, Functions/Procedures 5
Generating C source output to '.hbmk\win\mingw\PAGO-GEMI.c'... Done.
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0xa8): undefined reference to `HB_FUN_HPDF_NEW'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0xb8): undefined reference to `HB_FUN_HPDF_ADDPAGE'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0xc8): undefined reference to `HB_FUN_HPDF_PAGE_SETSIZE'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0xd8): undefined reference to `HB_FUN_HPDF_GETFONT'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0xe8): undefined reference to `HB_FUN_HPDF_LOADJPEGIMAGEFROMFILE'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0xf8): undefined reference to `HB_FUN_HPDF_PAGE_DRAWIMAGE'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x118): undefined reference to `HB_FUN_HPDF_PAGE_BEGINTEXT'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x128): undefined reference to `HB_FUN_HPDF_PAGE_SETFONT'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x138): undefined reference to `HB_FUN_HPDF_PAGE_TEXTOUT'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x158): undefined reference to `HB_FUN_HPDF_PAGE_ENDTEXT'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x1b8): undefined reference to `HB_FUN_HPDF_SAVETOFILE'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x1c8): undefined reference to `HB_FUN_HPDF_FREE'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x1d8): undefined reference to `HB_FUN_HPDF_PAGE_MOVETO'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x1e8): undefined reference to `HB_FUN_HPDF_PAGE_LINETO'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x1f8): undefined reference to `HB_FUN_HPDF_PAGE_STROKE'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x208): undefined reference to `HB_FUN_HPDF_PAGE_SETLINEWIDTH'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x218): undefined reference to `HB_FUN_HPDF_PAGE_RECTANGLE'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x238): undefined reference to `HB_FUN_HB_ZEBRA_CREATE_QR'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x248): undefined reference to `HB_FUN_HB_ZEBRA_DRAW'
.hbmk/win/mingw/PAGO-GEMI.o:PAGO-GEMI.c:(.data+0x258): undefined reference to `HB_FUN_HPDF_PAGE_FILL'
collect2.exe: error: ld returned 1 exit status
hbmk2[rep-pago]: Error: Ejecutando enlazador. 1



este es mi archivo PAGO-GEMI.PRG

Código: Selecionar todos

#include "hbxml.ch"
#include "hbhpdf.ch"
#include "hbzebra.ch"

#define MARGEN_IZQ 50
#define ANCHO_UTIL 512

PROCEDURE Main( cFileXml )
   LOCAL oXmlDoc, oComprobante, oEmisor, oReceptor, oPagos, oPago, oDoctoRel, oTfd, oTotales
   LOCAL oPdf, oPage, oFontBold, oFontNorm, nY := 750 //oFontTiny
   LOCAL cXmlContent, oImage, cLogo := "logo.jpg"

   IF Empty( cFileXml ) .OR. !File( cFileXml )
      ? "Error: Debe proporcionar un archivo XML valido."
      ? "Uso: rep_pago.exe PC000314.XML"
      RETURN
   ENDIF

   // --- 1. CARGA DE DATOS ---
   cXmlContent := MemoRead( cFileXml )
   oXmlDoc := TXmlDocument():New( cXmlContent )
   oComprobante := oXmlDoc:FindFirst( "cfdi:Comprobante" )
   oEmisor   := oComprobante:FindFirst( "cfdi:Emisor" )
   oReceptor := oComprobante:FindFirst( "cfdi:Receptor" )
   oTfd      := oXmlDoc:FindFirst( "tfd:TimbreFiscalDigital" )
   oPagos    := oComprobante:FindFirst( "pago20:Pagos" )
   oPago     := oPagos:FindFirst( "pago20:Pago" )
   oTotales  := oPagos:FindFirst( "pago20:Totales" )

   // --- 2. INICIALIZAR PDF ---
   oPdf := HPDF_New()
   oPage := HPDF_AddPage( oPdf )
   *HPDF_Page_SetSize( oPage, HPDF_PAGE_SIZE_LETTER, HPDF_PAGE_PORTRAIT )
   HPDF_Page_SetSize( oPage, 0, 0 )

   oFontBold := HPDF_GetFont( oPdf, "Helvetica-Bold" )
   oFontNorm := HPDF_GetFont( oPdf, "Helvetica" )
   *oFontTiny := HPDF_GetFont( oPdf, "Helvetica", 6 )

   // --- 3. ENCABEZADO Y LOGO ---
   IF File( cLogo )
      oImage := HPDF_LoadJpegImageFromFile( oPdf, cLogo )
      HPDF_Page_DrawImage( oPage, oImage, MARGEN_IZQ, 715, 90, 45 )
   ENDIF

   // Cuadro Emisor
   DibujarMarco( oPage, MARGEN_IZQ, 710, 250, 50 )
   HPDF_Page_BeginText( oPage )
   HPDF_Page_SetFont( oPage, oFontBold, 9 )
   HPDF_Page_TextOut( oPage, MARGEN_IZQ + 5, 700, "EMISOR: " + oEmisor:GetAttribute("Nombre") )
   HPDF_Page_SetFont( oPage, oFontNorm, 7 )
   HPDF_Page_TextOut( oPage, MARGEN_IZQ + 5, 690, "RFC: " + oEmisor:GetAttribute("Rfc") )
   HPDF_Page_TextOut( oPage, MARGEN_IZQ + 5, 680, "Regimen: " + oEmisor:GetAttribute("RegimenFiscal") )
   HPDF_Page_EndText( oPage )

   // Cuadro Receptor
   DibujarMarco( oPage, 310, 710, 250, 50 )
   HPDF_Page_BeginText( oPage )
   HPDF_Page_SetFont( oPage, oFontBold, 9 )
   HPDF_Page_TextOut( oPage, 315, 700, "RECEPTOR: " + oReceptor:GetAttribute("Nombre") )
   HPDF_Page_SetFont( oPage, oFontNorm, 7 )
   HPDF_Page_TextOut( oPage, 315, 690, "RFC: " + oReceptor:GetAttribute("Rfc") )
   HPDF_Page_TextOut( oPage, 315, 680, "Uso CFDI: " + oReceptor:GetAttribute("UsoCFDI") )
   HPDF_Page_EndText( oPage )

   // --- 4. TABLA DE DOCUMENTOS ---
   nY := 640
   ImprimirEncabezadoTabla( oPage, oFontBold, @nY )

   oDoctoRel := oPago:FindFirst( "pago20:DoctoRelacionado" )
   HPDF_Page_SetFont( oPage, oFontNorm, 7 )

   DO WHILE oDoctoRel != NIL
      IF nY < 180 // Control de Salto de Pagina
         oPage := HPDF_AddPage( oPdf )
         nY := 750
         ImprimirEncabezadoTabla( oPage, oFontBold, @nY )
         HPDF_Page_SetFont( oPage, oFontNorm, 7 )
      ENDIF

      HPDF_Page_BeginText( oPage )
      HPDF_Page_TextOut( oPage, 50,  nY, oDoctoRel:GetAttribute("Serie") + oDoctoRel:GetAttribute("Folio") )
      HPDF_Page_TextOut( oPage, 100, nY, oDoctoRel:GetAttribute("IdDocumento") )
      HPDF_Page_TextOut( oPage, 350, nY, Transform(Val(oDoctoRel:GetAttribute("ImpSaldoAnt")), "@E 999,999.99") )
      HPDF_Page_TextOut( oPage, 430, nY, Transform(Val(oDoctoRel:GetAttribute("ImpPagado")), "@E 999,999.99") )
      HPDF_Page_TextOut( oPage, 510, nY, Transform(Val(oDoctoRel:GetAttribute("ImpSaldoInsoluto")), "@E 999,999.99") )
      HPDF_Page_EndText( oPage )

      nY -= 10
      oDoctoRel := oPago:FindNext()
   ENDDO

   // --- 5. TOTALES ---
   nY -= 10
   DibujarMarco( oPage, 350, nY + 5, 230, 35 )
   HPDF_Page_BeginText( oPage )
   HPDF_Page_SetFont( oPage, oFontBold, 8 )
   HPDF_Page_TextOut( oPage, 360, nY - 5,  "Total IVA 16%:" )
   HPDF_Page_TextOut( oPage, 500, nY - 5,  Transform(Val(oTotales:GetAttribute("TotalTrasladosImpuestoIVA16")), "@E 999,999.99") )
   HPDF_Page_TextOut( oPage, 360, nY - 15, "MONTO TOTAL PAGO:" )
   HPDF_Page_TextOut( oPage, 500, nY - 15, Transform(Val(oPago:GetAttribute("Monto")), "@E 999,999.99") )
   HPDF_Page_EndText( oPage )

   // --- 6. PIE FISCAL ---
   ImprimirBloqueFiscal( oPdf, oPage, oTfd, oEmisor, oReceptor )

   HPDF_SaveToFile( oPdf, "Complemento_Pago.pdf" )
   HPDF_Free( oPdf )
   ? "Archivo 'Complemento_Pago.pdf' generado exitosamente."
RETURN

// --- FUNCIONES DE APOYO ---

PROCEDURE ImprimirEncabezadoTabla( oPage, oFont, nY )
   HPDF_Page_BeginText( oPage )
   HPDF_Page_SetFont( oPage, oFont, 8 )
   HPDF_Page_TextOut( oPage, 50,  nY, "FOLIO" )
   HPDF_Page_TextOut( oPage, 100, nY, "UUID RELACIONADO" )
   HPDF_Page_TextOut( oPage, 350, nY, "SALDO ANT." )
   HPDF_Page_TextOut( oPage, 430, nY, "PAGADO" )
   HPDF_Page_TextOut( oPage, 510, nY, "INSOLUTO" )
   HPDF_Page_EndText( oPage )
   nY -= 5
   HPDF_Page_MoveTo( oPage, 50, nY )
   HPDF_Page_LineTo( oPage, 580, nY )
   HPDF_Page_Stroke( oPage )
   nY -= 12
RETURN

PROCEDURE DibujarMarco( oPage, nX, nY, nW, nH )
   HPDF_Page_SetLineWidth( oPage, 0.5 )
   HPDF_Page_Rectangle( oPage, nX, nY - nH, nW, nH )
   HPDF_Page_Stroke( oPage )
RETURN

PROCEDURE ImprimirBloqueFiscal( oPdf, oPage, oTfd, oEmisor, oReceptor )
   LOCAL cUrl := "https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?" + ;
                 "id=" + oTfd:GetAttribute("UUID") + "&re=" + oEmisor:GetAttribute("Rfc") + ;
                 "&rr=" + oReceptor:GetAttribute("Rfc") + "&tt=0.00&fe=" + Right(oTfd:GetAttribute("SelloCFD"), 8)
   LOCAL hZebra := hb_zebra_create_qr( cUrl, NIL )
   LOCAL nY_F := 120

   // QR
   hb_zebra_draw( hZebra, {|x, y, w, h| HPDF_Page_Rectangle( oPage, 50 + x, nY_F - y, w, h ), HPDF_Page_Fill( oPage ) } )

   // Datos Fiscales
   HPDF_Page_BeginText( oPage )
   HPDF_Page_SetFont( oPage, HPDF_GetFont( oPdf, "Helvetica-Bold" ), 6 )
   HPDF_Page_TextOut( oPage, 140, nY_F, "Folio Fiscal (UUID): " + oTfd:GetAttribute("UUID") )
   HPDF_Page_SetFont( oPage, HPDF_GetFont( oPdf, "Helvetica" ), 5 )
   HPDF_Page_TextOut( oPage, 140, nY_F - 10, "Sello Digital del CFDI:" )
   ImprimirWrap( oPage, 140, nY_F - 17, oTfd:GetAttribute("SelloCFD"), 115 )
   HPDF_Page_EndText( oPage )
RETURN

PROCEDURE ImprimirWrap( oPage, nX, nY, cTexto, nLen )
   LOCAL nI := 1
   DO WHILE nI < Len(cTexto)
      HPDF_Page_TextOut( oPage, nX, nY, SubStr(cTexto, nI, nLen) )
      nI += nLen
      nY -= 6
   ENDDO
RETURN

Caulquier ayuda sera bienvenida
Saludos!!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20415
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

Re: Cómo crear un PDF a partir de un xml

Mensagem por JoséQuintas »

Se faltam funções, faltam fontes ou libs.
Prefixo HPDF, só pode ser harupdf
hb_zebran, só pode ser a zebra

Código: Selecionar todos

hpdf.hbc
hbzebra.hbc
Se quiser tirar dúvidas, peça ajuda pra hbmk2

Código: Selecionar todos

hbmk2 -find hpdf_
hbmk2 -find hb_zebra
hbmk2 sabe onde encontrar funções conhecidas, geralmente mostra uma ajuda no final da compilação
Isso significa que seu hbmk2 pode ser antigo, ou daqueles que vém de LIBs que apagam partes do harbour.
Ou.... está na parte que deixou de postar aqui.
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20415
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

Re: Cómo crear un PDF a partir de un xml

Mensagem por JoséQuintas »

NÃO É um teste de uso, é apenas teste de compilação.

Código: Selecionar todos


PROCEDURE Main

   SetMode(33,100)
   CLS
   hpdf_New()
   hb_Zebra()
   Inkey(0)

   RETURN
d:\temp>hbmk2 test
hbmk2: Processing environment options: -comp=mingw
hbmk2: Processing configuration: d:\harbour\bin\hbmk.hbc
Harbour 3.2.0dev (r2601171121)
Copyright (c) 1999-2025, https://harbour.github.io/
Compiling 'test.prg'...
Lines 20, Functions/Procedures 5
Generating C source output to 'C:\Users\joseq\AppData\Local\Temp\hbmk_faabq9.dir\test.c'... Done.
D:/harbour/comp/mingw32/bin/../lib/gcc/i686-w64-mingw32/15.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/Users/joseq/AppData/Local/Temp/hbmk_faabq9.dir/test.o:test.c:(.data+0x68): undefined reference to `HB_FUN_HPDF_NEW'
D:/harbour/comp/mingw32/bin/../lib/gcc/i686-w64-mingw32/15.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:/Users/joseq/AppData/Local/Temp/hbmk_faabq9.dir/test.o:test.c:(.data+0x78): undefined reference to `HB_FUN_HB_ZEBRA'
collect2.exe: error: ld returned 1 exit status
hbmk2: Error: Running linker. 1
,,,
hbmk2: Hint: Add option 'hbhpdf.hbc' for missing function(s): HPDF_New()
hbmk2: Error: Referenced, missing, but unknown function(s): HB_ZEBRA()
veja no final a dica do hbmk2 do que falta

ou o find, porque coloquei o nome da função zebra errado.
d:\temp>hbmk2 -find zebra
hbzebra.hbc (installed):
hb_zebra_create_codabar()
hb_zebra_create_code11()
hb_zebra_create_code128()
hb_zebra_create_code39()
hb_zebra_create_code93()
hb_zebra_create_datamatrix()
hb_zebra_create_ean13()
hb_zebra_create_ean8()
hb_zebra_create_itf()
hb_zebra_create_msi()
hb_zebra_create_pdf417()
hb_zebra_create_qrcode()
hb_zebra_create_upca()
hb_zebra_create_upce()
hb_zebra_destroy()
hb_zebra_draw()
hb_zebra_getbitmap()
hb_zebra_getcode()
hb_zebra_geterror()
hb_zebra_getsize()
__HBEXTERN__HBZEBRA__()
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder