Linux环境下DinkToPdf转换PDF时图片不显示问题求助
问题描述
我有一个基于.NET 6的Web API项目,使用DinkToPdf实现HTML转PDF功能,开发环境为macOS,部署在Linux Ubuntu 20.4和Windows Server 2012服务器上,API会根据运行操作系统加载对应库。
控制器核心代码如下:
public class ClientDocController : BaseController { private readonly IClientAppointmentDocumentService _clientAppointmentDocumentService; private readonly IConverter _htmlToPdfConverter; public ClientDocController(IClientAppointmentDocumentService clientAppointmentDocumentService, IConverter htmlToPdfConverter) { _clientAppointmentDocumentService = clientAppointmentDocumentService; _htmlToPdfConverter = htmlToPdfConverter; } [HttpGet("{documentId}/pdf/")] [RestApiAuthorize(AccountRolePermissions.VIEW_CLIENT_DOCUMENTS)] public async Task<IActionResult> GetPdfAsync([FromRoute] int documentId, bool uploadToClientPortal, int? templateId = null, bool clientPrint = false, bool sendToClientEmail = false, CancellationToken cancellationToken = default) { try { var htmlDocument = templateId == null ? await _clientAppointmentDocumentService.GetDefaultHtmlDocumentAsync(documentId, clientPrint, cancellationToken) : await _clientAppointmentDocumentService.GetHtmlDocumentAsync(documentId, templateId, clientPrint, cancellationToken); var fileName = $"Document_{documentId}_{DateTime.Now:s}.pdf"; var conversionSettings = PdfConfigurationDefaults.GetDefaultSettings(htmlDocument); // 获取各平台独立配置 var pdf = _htmlToPdfConverter.Convert(conversionSettings); var result = File(pdf, MediaTypeNames.Application.Pdf, fileName); if (sendToClientEmail) await _clientAppointmentDocumentService.SendToClientByEmailAsync(new[] {result}); if (!uploadToClientPortal) return result; var accessToken = Request.Headers["Authorization"].ToString(); var response = await _clientAppointmentDocumentService.UploadToClientPortalAsync(documentId, result, accessToken); return Ok(response); } catch (Exception e) { return BadRequest(e.Message); } } }
功能在所有机器上均可正常运行,但Linux服务器上生成的PDF中,<img src="https://..." />标签的图片无法显示。
已排查内容:
- 非SSL问题:直接让控制器输出HTML时图片可正常显示;
- 尝试了
conversionSettings中的多种配置(未尝试所有组合),均无效; - 将图片转为base64字符串也无法解决问题。
排查方向
- 检查Linux服务器的网络访问权限:DinkToPdf依赖的wkhtmltopdf在Linux下可能无法访问外部HTTPS资源,可通过服务器防火墙、安全组规则排查是否限制出站请求,或是否需要配置代理。用
curl命令测试图片URL的可访问性:curl -O https://你的图片URL,确认能否正常下载图片。 - 验证wkhtmltopdf的系统依赖:Linux下的wkhtmltopdf需要依赖libx11、libxext、libfontconfig等系统库,缺失会导致图片加载失败。运行
wkhtmltopdf --version查看版本,再用ldd /path/to/wkhtmltopdf检查依赖库是否齐全,缺失的话通过apt-get install libx11-dev libxext-dev libfontconfig1-dev等命令补全。 - 明确图片的尺寸属性:wkhtmltopdf在Linux下对未指定尺寸的图片处理可能异常,尝试给
<img>标签添加明确的width/height属性或CSS样式,比如<img src="https://..." style="width:200px;height:auto;" />。 - 开启转换调试日志:在
conversionSettings中启用调试参数,比如设置DebugJavascript = true、Verbose = true,或指定日志文件路径,查看转换过程中是否有图片加载超时、资源无法获取的具体错误提示。 - 测试本地图片引用:将图片下载到Linux服务器本地,用绝对路径引用(比如
<img src="/var/www/assets/test.jpg" />),验证是否能正常显示,以此排除远程资源的网络问题。 - 检查进程用户权限:运行API的进程用户(如www-data)是否具备访问外部网络或读取本地资源的权限。切换到该用户,执行
curl命令测试图片URL,确认权限是否充足。 - 临时禁用证书验证:虽然已排除SSL问题,但wkhtmltopdf在Linux下可能对部分证书链不信任,可在
conversionSettings的Arguments中添加--no-check-certificate参数,临时测试是否能加载图片,排查证书信任问题。
内容的提问来源于stack exchange,提问作者Tropin Alexey
相关产品推荐
相关产品推荐

