使用pdfkit和wkhtmltopdf生成带TOC的PDF时目录空白问题排查
我需要将一个HTML文件转换为PDF,代码如下:
import pdfkit #Define path to wkhtmltopdf.exe path_to_wkhtmltopdf = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe' #Define path to HTML file path_to_file = "database-pdf.html" #Define path to css file css_path = "print.css" #Point pdfkit configuration to wkhtmltopdf.exe config = pdfkit.configuration(wkhtmltopdf=path_to_wkhtmltopdf) cover = "cover.html" toc = { "xsl-style-sheet": "toc.xsl" } options = { "enable-local-file-access": None, "page-height": "297mm", "page-width": "210mm", } #Convert HTML file to PDF pdfkit.from_file(path_to_file, css=css_path, output_path='database.pdf', configuration=config, options=options, toc=toc, cover=cover, cover_first=True )
使用的是wkhtmltopdf 0.12.6版本,toc.xsl是从wkhtmltopdf导出的基础样式文件。生成PDF时目录(TOC)页面空白,但直接用wkhtmltopdf命令行工具生成时目录功能正常。添加verbose参数后得到以下日志:
QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files Counting pages (2/6) Error XTSE0010 in file:///C:/Program%20Files/wkhtmltopdf/bin/wkhtmltopdf.exe, at line 1, column 38: Parse error: Encountered incorrectly encoded content. Loading TOC (3/6) Error XTSE0010 in file:///C:/Program%20Files/wkhtmltopdf/bin/wkhtmltopdf.exe, at line 1, column 38: Parse error: Encountered incorrectly encoded content. Resolving links (4/6) Loading headers and footers (5/6) Printing pages (6/6) Warning: Received createRequest signal on a disposed ResourceObject's NetworkAccessManager. This might be an indication of an iframe taking too long to load. Done Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
请问哪里操作出错了?
从日志中的XTSE0010错误可以定位核心问题:wkhtmltopdf错误地将自身可执行文件(C:/Program Files/wkhtmltopdf/bin/wkhtmltopdf.exe)当作TOC的XSL样式表读取,导致解析失败,最终TOC页面空白。
问题根源
pdfkit在处理字典格式的toc参数时,对xsl-style-sheet的路径解析存在偏差,使用相对路径时无法正确传递给wkhtmltopdf,进而触发程序误读自身文件。
修复方法
使用绝对路径指定toc.xsl
把相对路径转换为绝对路径,避免解析错误:import os # 获取toc.xsl的绝对路径 toc_xsl_path = os.path.abspath("toc.xsl") toc = { "xsl-style-sheet": toc_xsl_path }直接在options中指定TOC参数
绕过字典形式的toc参数,直接在options里添加TOC相关配置(参考wkhtmltopdf命令行参数格式):options = { "enable-local-file-access": None, "page-height": "297mm", "page-width": "210mm", "toc": "", "xsl-style-sheet": os.path.abspath("toc.xsl") }此时调用
pdfkit.from_file时无需再传递toc=toc参数。添加文件协议前缀(可选)
如果上述方法无效,给路径加上file://前缀,符合日志提示的URL规范:toc_xsl_path = f"file:///{os.path.abspath('toc.xsl').replace('\\', '/')}"
补充说明
命令行能正常生成TOC是因为你直接指定了正确的XSL路径,而pdfkit的参数封装层在处理字典形式的toc参数时出现了路径解析问题,改用绝对路径或直接在options中配置即可解决。
内容的提问来源于stack exchange,提问作者green_bean_cake

