Ubuntu环境下DinkToPdf Converter返回空字节数组问题咨询
DinkToPdf 部署到Ubuntu Apache环境返回空PDF字节数组问题处理
问题复现代码
var converter = new SynchronizedConverter(new PdfTools()); var doc = new HtmlToPdfDocument() { GlobalSettings = { ColorMode = ColorMode.Color, Orientation = Orientation.Portrait, PaperSize = PaperKind.A4, Margins = new MarginSettings() { Top = 10 }, }, Objects = { new ObjectSettings() { Page = "https://en.wikipedia.org/wiki/Main_Page", }, } }; try { byte[] pdf = converter.Convert(doc); FileResult fileResult = new FileContentResult(pdf, "application/pdf") { FileDownloadName = "wikipedia_main_page.pdf" }; return fileResult; } catch (Exception e) { return JsonConvert.SerializeObject(e); }
问题表现
上述代码在Windows环境运行正常,可正常生成PDF;部署到搭载Apache的Ubuntu服务器后,代码执行无托管层异常抛出,但Convert()方法返回空字节数组,无有效PDF内容。部署时未区分平台原生库,直接将包含.dll、.so、.dylib格式的全量原生库复制到了服务器。
核心产生原因
- 原生库加载错误:DinkToPdf是基于
libwkhtmltox原生C++库的.NET封装,不同操作系统、不同CPU架构对应的原生库二进制完全不兼容。混放全平台库文件时,程序可能加载到错误架构、错误版本的.so文件,甚至尝试加载macOS专属的.dylib、Windows专属的.dll文件,导致原生库初始化失败。且DinkToPdf托管层未对这类加载错误做完整的异常封装,不会触发catch块捕获,直接返回空结果。 - 系统依赖缺失:
libwkhtmltox运行依赖X11渲染组件、字体配置库、图片解码库、OpenSSL等系统级组件,最小化安装的Ubuntu默认不带这些依赖,原生渲染引擎启动失败时同样不会抛出托管异常。 - 权限配置错误:Apache默认运行身份为
www-data,如果该用户对库存放路径、临时文件目录(默认/tmp)没有读写执行权限,原生库无法生成临时渲染缓存,会静默返回空结果。 - 库搜索路径异常:未明确指定适配的.so库路径时,程序按系统默认动态库搜索顺序查找文件,可能加载到不兼容的版本,或完全找不到目标库。
解决步骤
- 清理冗余原生库
部署到Ubuntu时,删除项目目录下所有.dll、.dylib格式的DinkToPdf原生文件,仅保留和服务器CPU架构完全匹配的Linux版本libwkhtmltox.so文件(推荐使用0.12.6稳定版,x64架构服务器不要混用arm64版本的so文件)。 - 安装系统运行依赖
执行以下命令安装原生库必须的依赖组件,附带安装开源中文字体避免中文内容乱码:apt update apt install -y libgdiplus libx11-dev libx11-xcb1 libxcb1 libxcb-render0 libxcb-shm0 libxrender1 libxext6 libssl-dev libfreetype6 libfontconfig1 libjpeg-turbo8 libpng16-16 libstdc++6 fonts-wqy-microhei fonts-wqy-zenhei - 配置库路径与权限
- 将适配版本的
libwkhtmltox.so复制到/usr/lib/目录,执行ldconfig刷新系统动态库缓存。 - 给库文件添加可执行权限:
chmod +x /usr/lib/libwkhtmltox.so - 给临时目录开放权限供原生库写入渲染缓存:
chmod 777 /tmp - 确认Apache运行用户
www-data对项目部署目录所有文件有读权限。
- 将适配版本的
- 代码层明确指定库加载路径
初始化转换器时明确指定Linux环境下的库绝对路径,避免加载错误版本:var converter = new SynchronizedConverter(new PdfTools(), new DinkToPdf.Settings.LoadSettings() { LibraryPath = "/usr/lib/libwkhtmltox.so" }); - 配置Apache环境变量
部分Apache配置会重置运行时动态库搜索路径,编辑Apache环境配置文件,添加LD_LIBRARY_PATH=/usr/lib配置项后重启Apache服务生效。
内容的提问来源于stack exchange,提问作者Borislav Nanovski
相关产品推荐
相关产品推荐

