[UDF] wkHTMLtoPDF (DLL)

Partagez des fonctions et des UDF AutoIt.
Règles du forum
.
Répondre
Avatar du membre
matwachich
Membre émérite
Membre émérite
Messages : 986
Enregistré le : lun. 19 oct. 2009 04:04
Localisation : Algérie
Status : Hors ligne

[UDF] wkHTMLtoPDF (DLL)

#1

Message par matwachich »

Salut!
Un petit UDF tout simple pour convertir du HTML en PDF, avec tout pleins d'options (vu que ça se base sur l'excellent et OpenSource wkHTMLtoPDF).
L'avantage de cet UDF c'est que ça utilise la DLL de wkHTMLtoPDF, et pas l'exacutable (donc pas de processus externe).

Le voici: https://github.com/matwachich/wkhtmltopdf-au3

Ciao ;)

Edit:
- L'UDF est un wrapper pour la version 0.12.5 de wkHTMLtoPDF. Pour télécharger les DLLs nécessaires, c'est par ici https://wkhtmltopdf.org/downloads.html (prenez l'archive Windows, MXE (MinGW-w64), 32/64 bits selon les cas)
- Au cas ou le Git disparait, voici les sources (commit initial du 18 juin 2019):

UDF:

Code : Tout sélectionner

#include-once
#include <WinAPI.au3>

Global $__gHTML2PDF_hDLL = -1

; -------------------------------------------------------------------------------------------------

;~ CAPI(int) wkhtmltopdf_init(int use_graphics);
Func _HTML2PDF_Init($sDllPath, $bUseGraphics = False)
	If $__gHTML2PDF_hDLL = -1 Then
		$__gHTML2PDF_hDLL = DllOpen($sDllPath)
		If $__gHTML2PDF_hDLL = -1 Then Return SetError(-1, 0, False)

		DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_init", "int", $bUseGraphics)
		If @error Then Return SetError(@error, 0, False)
	EndIf
	Return True
EndFunc

;~ CAPI(int) wkhtmltopdf_deinit();
Func _HTML2PDF_Deinit()
	If $__gHTML2PDF_hDLL <> -1 Then
		DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_deinit")
		If @error Then Return SetError(@error, 0, False)

		DllClose($__gHTML2PDF_hDLL)
		$__gHTML2PDF_hDLL = -1
	EndIf
	Return True
EndFunc

;~ CAPI(int) wkhtmltopdf_extended_qt();
Func _HTML2PDF_ExtendedQT()
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_extended_qt")
	If @error Then Return SetError(@error, 0, 0)
	Return $aRet[0]
EndFunc

;~ CAPI(const char *) wkhtmltopdf_version();
Func _HTML2PDF_Version()
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "str", "wkhtmltopdf_version")
	If @error Then Return SetError(@error, 0, "")
	Return $aRet[0]
EndFunc

; -------------------------------------------------------------------------------------------------

;~ CAPI(wkhtmltopdf_global_settings *) wkhtmltopdf_create_global_settings();
;~ CAPI(void) wkhtmltopdf_destroy_global_settings(wkhtmltopdf_global_settings *);
Func _HTML2PDF_CreateGlobalSettings()
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "ptr", "wkhtmltopdf_create_global_settings")
	If @error Then Return SetError(@error, 0, Null)
	Return $aRet[0]
EndFunc

Func _HTML2PDF_DestroyGlobalSettings($pGlobalSettings)
	DllCall($__gHTML2PDF_hDLL, "none", "wkhtmltopdf_destroy_global_settings", "ptr", $pGlobalSettings)
EndFunc

;~ CAPI(wkhtmltopdf_object_settings *) wkhtmltopdf_create_object_settings();
;~ CAPI(void) wkhtmltopdf_destroy_object_settings(wkhtmltopdf_object_settings *);
Func _HTML2PDF_CreateObjectSettings()
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "ptr", "wkhtmltopdf_create_object_settings")
	If @error Then Return SetError(@error, 0, Null)
	Return $aRet[0]
EndFunc

Func _HTML2PDF_DestroyObjectSettings($pObjectSettings)
	DllCall($__gHTML2PDF_hDLL, "none", "wkhtmltopdf_destroy_object_settings", "ptr", $pObjectSettings)
EndFunc

;~ CAPI(int) wkhtmltopdf_set_global_setting(wkhtmltopdf_global_settings * settings, const char * name, const char * value);
;~ CAPI(int) wkhtmltopdf_get_global_setting(wkhtmltopdf_global_settings * settings, const char * name, char * value, int vs);
Func _HTML2PDF_SetGlobalSetting($pGlobalSettings, $sKey, $sValue)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_set_global_setting", "ptr", $pGlobalSettings, "str", $sKey, "struct*", __html2pdf_str2UTF8struct($sValue))
	If @error Then Return SetError(@error, 0, Null)
	Return $aRet[0]
EndFunc

Func _HTML2PDF_GetGlobalSetting($pGlobalSettings, $sKey, $iBuffSize = 1024)
	Local $tBuff = DllStructCreate("byte[" & $iBuffSize & "]")
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_get_global_setting", "ptr", $pGlobalSettings, "str", $sKey, "struct*", $tBuff, "int", $iBuffSize)
	If @error Then Return SetError(@error, 0, "")
	Return BinaryToString(BinaryMid(DllStructGetData($tBuff, 1), 1, _WinAPI_StrLen(DllStructGetPtr($tBuff, 1), False)), 4)
EndFunc

;~ CAPI(int) wkhtmltopdf_set_object_setting(wkhtmltopdf_object_settings * settings, const char * name, const char * value);
;~ CAPI(int) wkhtmltopdf_get_object_setting(wkhtmltopdf_object_settings * settings, const char * name, char * value, int vs);
Func _HTML2PDF_SetObjectSetting($pObjectSettings, $sKey, $sValue)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_set_object_setting", "ptr", $pObjectSettings, "str", $sKey, "struct*", __html2pdf_str2UTF8struct($sValue))
	If @error Then Return SetError(@error, 0, Null)
	Return $aRet[0]
EndFunc

Func _HTML2PDF_GetObjectSetting($pObjectSettings, $sKey, $iBuffSize = 1024)
	Local $tBuff = DllStructCreate("byte[" & $iBuffSize & "]")
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_get_object_setting", "ptr", $pObjectSettings, "str", $sKey, "struct*", $tBuff, "int", $iBuffSize)
	If @error Then Return SetError(@error, 0, "")
	Return BinaryToString(BinaryMid(DllStructGetData($tBuff, 1), 1, _WinAPI_StrLen(DllStructGetPtr($tBuff, 1), False)), 4)
EndFunc

; -------------------------------------------------------------------------------------------------

;~ CAPI(wkhtmltopdf_converter *) wkhtmltopdf_create_converter(wkhtmltopdf_global_settings * settings);
;~ CAPI(void) wkhtmltopdf_destroy_converter(wkhtmltopdf_converter * converter);
Func _HTML2PDF_CreateConverter($pGlobalSettings)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "ptr", "wkhtmltopdf_create_converter", "ptr", $pGlobalSettings)
	If @error Then Return SetError(@error, 0, Null)
	Return $aRet[0]
EndFunc

Func _HTML2PDF_DestroyConverter($pConverter)
	DllCall($__gHTML2PDF_hDLL, "none", "wkhtmltopdf_destroy_converter", "ptr", $pConverter)
EndFunc

;~ CAPI(void) wkhtmltopdf_set_warning_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_str_callback cb);
;~ CAPI(void) wkhtmltopdf_set_error_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_str_callback cb);
;~ CAPI(void) wkhtmltopdf_set_phase_changed_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_void_callback cb);
;~ CAPI(void) wkhtmltopdf_set_progress_changed_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_int_callback cb);
;~ CAPI(void) wkhtmltopdf_set_finished_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_int_callback cb);
Func _HTML2PDF_SetCallback($pConverter, $sCallback, $pfnCallback) ; $sCallback = warning|error|phase_changed|progress|finished
	Switch $sCallback
		Case "warning", "error"
			$pfnCallback = DllCallbackRegister($pfnCallback, "none", "ptr;str") ; typedef void (*wkhtmltopdf_str_callback)(wkhtmltopdf_converter * converter, const char * str);
		Case "progress", "finished"
			$pfnCallback = DllCallbackRegister($pfnCallback, "none", "ptr;int") ; typedef void (*wkhtmltopdf_int_callback)(wkhtmltopdf_converter * converter, const int val);
		Case Else
			$pfnCallback = DllCallbackRegister($pfnCallback, "none", "ptr") ; typedef void (*wkhtmltopdf_void_callback)(wkhtmltopdf_converter * converter);
	EndSwitch
	DllCall($__gHTML2PDF_hDLL, "none", "wkhtmltopdf_set_" & $sCallback & "_callback", "ptr", $pConverter, "ptr", DllCallbackGetPtr($pfnCallback))
	If @error Then Return SetError(@error, 0, False)
	Return True
EndFunc

;~ CAPI(int) wkhtmltopdf_convert(wkhtmltopdf_converter * converter);
Func _HTML2PDF_Convert($pConverter)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_convert", "ptr", $pConverter)
	If @error Then Return SetError(@error, 0, False)
	Return $aRet[0]
EndFunc

;~ CAPI(void) wkhtmltopdf_add_object(wkhtmltopdf_converter * converter, wkhtmltopdf_object_settings * setting, const char * data);
Func _HTML2PDF_AddObject($pConverter, $pObjectSettings, $sData = Null)
	Local $tData = Null
	If $sData Then
		$sData = StringToBinary($sData, 4)
		$tData = DllStructCreate("byte[" & (BinaryLen($sData) + 1) & "]")
		DllStructSetData($tData, 1, $sData)
	EndIf
	DllCall($__gHTML2PDF_hDLL, "none", "wkhtmltopdf_add_object", "ptr", $pConverter, "ptr", $pObjectSettings, "struct*", $tData)
	If @error Then Return SetError(@error, 0, False)
	Return True
EndFunc

; -------------------------------------------------------------------------------------------------

;~ CAPI(int) wkhtmltopdf_current_phase(wkhtmltopdf_converter * converter);
Func _HTML2PDF_CurrentPhase($pConverter)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_current_phase", "ptr", $pConverter)
	If @error Then Return SetError(@error, 0, 0)
	Return $aRet[0]
EndFunc

;~ CAPI(int) wkhtmltopdf_phase_count(wkhtmltopdf_converter * converter);
Func _HTML2PDF_PhaseCount($pConverter)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_phase_count", "ptr", $pConverter)
	If @error Then Return SetError(@error, 0, 0)
	Return $aRet[0]
EndFunc

;~ CAPI(const char *) wkhtmltopdf_phase_description(wkhtmltopdf_converter * converter, int phase);
Func _HTML2PDF_PhaseDescription($pConverter, $iPhase)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "str", "wkhtmltopdf_phase_description", "ptr", $pConverter, "int", $iPhase)
	If @error Then Return SetError(@error, 0, "")
	Return $aRet[0]
EndFunc

;~ CAPI(const char *) wkhtmltopdf_progress_string(wkhtmltopdf_converter * converter);
Func _HTML2PDF_ProgressString($pConverter)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "str", "wkhtmltopdf_progress_string", "ptr", $pConverter)
	If @error Then Return SetError(@error, 0, "")
	Return $aRet[0]
EndFunc

;~ CAPI(int) wkhtmltopdf_http_error_code(wkhtmltopdf_converter * converter);
Func _HTML2PDF_HTTPErrorCode($pConverter)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "int", "wkhtmltopdf_http_error_code", "ptr", $pConverter)
	If @error Then Return SetError(@error, 0, 0)
	Return $aRet[0]
EndFunc

;~ CAPI(long) wkhtmltopdf_get_output(wkhtmltopdf_converter * converter, const unsigned char **);
Func _HTML2PDF_GetOutput($pConverter)
	Local $aRet = DllCall($__gHTML2PDF_hDLL, "long", "wkhtmltopdf_get_output", "ptr", $pConverter, "ptr*", 0)
	If @error Then Return SetError(@error, 0, Binary(""))
	Return DllStructGetData(DllStructCreate("byte[" & $aRet[0] & "]", $aRet[2]), 1)
EndFunc

; -------------------------------------------------------------------------------------------------
; internals

Func __html2pdf_str2UTF8struct($sText)
	$sText = StringToBinary($sText, 4)
	Local $struct = DllStructCreate("byte[" & (BinaryLen($sText) + 1) & "]")
	DllStructSetData($struct, 1, $sText)
	Return $struct
EndFunc
Exemple:

Code : Tout sélectionner

#NoTrayIcon
#include "wkhtmltopdf.au3"

Global $sDllPath
If @AutoItX64 Then
	$sDllPath = @ScriptDir & "\wkhtmltox-x64.dll"
Else
	$sDllPath = @ScriptDir & "\wkhtmltox-x86.dll"
EndIf

Global $sHTML = FileRead("test.html")

For $i = 1 To 1
	Call(StringFormat("_Example%02d", $i))
Next

; simplest
Func _Example01()
	ConsoleWrite(@CRLF & "-----------" & @CRLF & "Example 01: Simplest" & @CRLF)

	; init
	_HTML2PDF_Init($sDllPath)
	ConsoleWrite("Init done (@error=" & @error & ")" & @CRLF)

	; create settings (all default)
	$pGS = _HTML2PDF_CreateGlobalSettings()
	$pOS = _HTML2PDF_CreateObjectSettings()

	; create converter
	$pConverter = _HTML2PDF_CreateConverter($pGS)

	; optional: add callbacks
	_HTML2PDF_SetCallback($pConverter, "warning", __callback_warning)
	_HTML2PDF_SetCallback($pConverter, "error", __callback_error)
	_HTML2PDF_SetCallback($pConverter, "phase_changed", __callback_phase_changed)
	_HTML2PDF_SetCallback($pConverter, "progress", __callback_progress)
	_HTML2PDF_SetCallback($pConverter, "finished", __callback_finished)

	; add HTML source to convert
	_HTML2PDF_AddObject($pConverter, $pOS, $sHTML)

	; do conversion
	_HTML2PDF_Convert($pConverter)
	$bOutput = _HTML2PDF_GetOutput($pConverter)

	$hF = FileOpen("example01.pdf", 2 + 8 + 128)
	FileWrite($hF, Binary($bOutput))
	FileClose($hF)

	; cleanup
	_HTML2PDF_DestroyConverter($pConverter)
	_HTML2PDF_DestroyObjectSettings($pOS)
	_HTML2PDF_DestroyGlobalSettings($pGS)
	_HTML2PDF_Deinit()
EndFunc

; -------------------------------------------------------------------------------------------------

Func __callback_warning($pConverter, $sText)
	ConsoleWrite("Warning: " & $sText & @CRLF)
EndFunc
Func __callback_error($pConverter, $sText)
	ConsoleWrite("ERROR: " & $sText & @CRLF)
EndFunc
Func __callback_phase_changed($pConverter)
	Local $iPhase = _HTML2PDF_CurrentPhase($pConverter)
	ConsoleWrite("Phase " & ($iPhase + 1) & "/" & _HTML2PDF_PhaseCount($pConverter) & ": " & _HTML2PDF_PhaseDescription($pConverter, $iPhase) & @CRLF)
EndFunc
Func __callback_progress($pConverter, $iData)
	ConsoleWrite("Progress: " & $iData & " (" & _HTML2PDF_ProgressString($pConverter) & ")" & @CRLF)
EndFunc
Func __callback_finished($pConverter, $iData)
	ConsoleWrite("DONE (" & $iData & ")" & @CRLF)
EndFunc
Modifié en dernier par matwachich le sam. 06 juil. 2019 23:54, modifié 1 fois.
Sortons VW du coté obscure! - La curiosité est un vilain défaut! Cliquez ici
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11772
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [UDF] wkHTMLtoPDF (DLL)

#2

Message par Tlem »

Merci Mat, mais si demain ton Git disparait, ce message ne servira absolument à rien.
Je préfèrerais que tu place les sources ici en l'état et que tu laisse ton lien vers le Git, pour ceux qui veulent la dernière version ou le complet.
Concernant les Dll, vu leurs taille, le lien vers le Git ou un lien vers le site original suffira. ^^
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Répondre