WickedPdf生成PDF时Settings表中图片无法显示问题求助
解决WickedPdf生成PDF时无法显示上传图片的问题
问题原因
WickedPdf依赖webkit渲染HTML生成PDF,直接使用相对路径(如/uploads/setting/logo/1/America_1.png)的图片时,webkit无法确定资源的完整访问路径,导致加载失败;而wicked_pdf_asset_base64是将本地资源转成Base64嵌入HTML,所以能正常显示。
解决方案
方案1:生成图片的绝对URL
在Service的render_to_string调用中补充host和protocol参数,确保image_tag生成完整的绝对路径:
修改FileService::LetterGenerator的process方法:
module FileService class LetterGenerator def initialize(user) @user = user end def process default_url_options = Rails.application.routes.default_url_options WickedPdf.new.pdf_from_string( ApplicationController.new.render_to_string( template: 'services/main.pdf.erb', locals: { user: user }, host: default_url_options[:host], protocol: default_url_options[:protocol] || 'https' ), margin: { top: 10, bottom: 20 } ) end private attr_reader :user end end
模板中的image_tag无需修改,此时会生成类似https://your-domain.com/uploads/setting/logo/1/America_1.png的绝对URL,webkit可以正常加载。
方案2:将上传图片转为Base64嵌入HTML
如果服务器环境无法通过外部URL访问上传文件(如本地开发或内网环境),可以直接读取本地文件转为Base64编码,避免依赖外部访问:
修改main.pdf.erb中的图片渲染部分:
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> <div class="letter"> <div class='header'> <div class='header-right'> <b>Letter</b> </div> <div class='logo'> <% if user.client %> <% logo_file_path = Rails.root.join('public', Setting.take.logo.url.delete_prefix('/')) %> <% if File.exist?(logo_file_path) %> <%= image_tag "data:image/png;base64,#{Base64.encode64(File.read(logo_file_path))}", size: "100x50" %> <% else %> <%= image_tag wicked_pdf_asset_base64('mailer/logo.png') %> <% end %> <% else %> <%= image_tag wicked_pdf_asset_base64('mailer/logo.png') %> <% end %> </div> </div> </div>
注意:要根据图片实际格式调整
data:image/png中的类型(如jpg对应image/jpeg),同时添加文件存在判断避免报错。
关键说明
- 方案1适合生产环境,依赖服务器的外部访问能力;
- 方案2更通用,不依赖外部URL,适合各种环境,但大图片会增加HTML体积。
内容的提问来源于stack exchange,提问作者user12763413
相关产品推荐
相关产品推荐

