You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PhantomJS生成PDF中文及特殊字符乱码问题排查咨询

问题根本原因
  • 你观察到的乱码特征("骆高" → "éªé«"、"TÜV" → "TÃV")是UTF-8编码字节被强制按ISO-8859-1(Latin-1)单字节编码解析的典型表现,和ASCII编码无关。
  • 核心问题1:PhantomJS 1.9.8版本的stdin读取逻辑默认继承系统编码,不会自动识别传入的UTF-8格式参数。你在Node侧调用child.stdin.write时指定了utf8编码,所有Node侧日志打印正常,但PhantomJS执行渲染的pdf_a4_portrait.js脚本读取stdin输入时,没有显式指定UTF-8编码,拿到的HTML字符串在渲染前就已经是乱码状态。这也是你之前加meta标签、设置phantom.outputEncoding都不生效的原因——phantom.outputEncoding仅控制PhantomJS输出日志的编码,完全不影响stdin读取、页面渲染的编码逻辑。
  • 核心问题2:Galaxy部署用的是精简Linux容器镜像,默认没有预装中文字体和CJK兼容字体包,PhantomJS渲染PDF时找不到对应字符的字形映射,即使编码传递正确也可能出现乱码、方块字问题。
  • 额外配置错误:你写入S3时使用new Buffer(buffer, 'utf8')处理PDF文件是错误逻辑,fs.readFile拿到的PDF内容是二进制Buffer,强行指定utf8转码会破坏二进制文件结构,反而可能加剧内容异常。
可行修复方案

按优先级依次操作即可解决问题:

  • 修复PhantomJS侧stdin读取编码
    打开项目路径下的assets/packages/fta_phantomjs/scripts/pdf_a4_portrait.js脚本,找到读取stdin输入的代码段,显式指定编码为UTF-8,参考修改:
    var system = require('system');
    var input = '';
    // 新增该行,强制stdin按UTF-8编码读取
    system.stdin.setEncoding('utf8');
    
    system.stdin.on('data', function(chunk) {
      input += chunk;
    });
    
    system.stdin.on('end', function() {
      // 再解析JSON参数,此时拿到的html字段编码正常
      var args = JSON.parse(input);
      // 后续保留原有页面渲染、PDF生成逻辑即可
    });
    
    注意:PhantomJS 1.9.x版本的编码自动识别存在已知bug,必须显式设置编码,不能依赖默认逻辑。
  • 补全Galaxy运行环境字体依赖
    在项目构建流程中添加字体安装步骤,确保容器内有可用的中文字体:
    1. 在项目根目录新建galaxy-postinstall.sh脚本:
    #!/bin/bash
    apt-get update -y
    apt-get install -y --no-install-recommends fonts-wqy-zenhei fonts-wqy-microhei fonts-noto-cjk fontconfig
    fc-cache -fv
    
    1. 在项目package.json中添加postinstall钩子,保证Galaxy部署时自动执行脚本:
    "scripts": {
      "postinstall": "chmod +x ./galaxy-postinstall.sh && ./galaxy-postinstall.sh"
    }
    
  • 清理无效配置、修正错误逻辑
    • 删除S3上传时的多余编码指定,直接传读取到的二进制Buffer即可:
      s3.putObject
        Bucket: "<Bucket>"
        Key: "<Key>"
        Body: buffer # 去掉new Buffer和utf8参数,直接传读出来的二进制内容
        ContentType: 'application/pdf'
      
    • HTML模板里只保留一个<meta charset="utf-8" />标签即可,重复添加的http-equiv meta标签属于冗余配置,不会提升兼容性,可以删掉。
    • child.stdin.setEncoding('utf8')、child.stdout.setEncoding('utf8')的配置可以保留,不影响功能。
  • 长期优化建议
    PhantomJS 1.9.8是2014年发布的老旧版本,存在大量编码、渲染兼容bug,条件允许的话建议升级到PhantomJS 2.1.3版本,或者直接迁移到Puppeteer,对Unicode、中文字体的支持稳定性远高于老版本PhantomJS。

内容的提问来源于stack exchange,提问作者johanmetlef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 09:30:39