编译wkhtmltopdf支持中文字体:字体库集成与配置方法
引言:为什么wkhtmltopdf中文显示会乱码?
你是否在使用wkhtmltopdf将HTML转换为PDF时遇到过中文显示乱码、方块或空白的问题?这是因为wkhtmltopdf基于WebKit引擎渲染,默认情况下可能不包含中文字体支持。本文将详细介绍如何在编译wkhtmltopdf时集成中文字体,并提供全面的配置方法,确保中文内容完美呈现。
读完本文,你将能够:
- 理解wkhtmltopdf字体渲染原理
- 准备中文字体文件并正确配置编译环境
- 修改源代码以支持自定义字体嵌入
- 编译支持中文字体的wkhtmltopdf版本
- 验证字体渲染效果并解决常见问题
wkhtmltopdf字体渲染原理
WebKit字体渲染流程
wkhtmltopdf使用QtWebKit引擎进行HTML渲染,其字体处理流程如下:
中文字体缺失的常见原因
- 编译时未包含中文字体:默认编译配置不包含中文字体文件
- 系统字体路径问题:程序无法找到系统安装的中文字体
- 字体配置错误:CSS中指定的字体名称与实际可用字体不匹配
- 字体格式不支持:WebKit对某些字体格式支持有限
编译前准备工作
环境要求
| 操作系统 | 最低版本 | 推荐版本 |
|---|---|---|
| Ubuntu | 16.04 | 20.04 LTS |
| CentOS | 7 | 8 |
| macOS | 10.13 | 12.0+ |
| Windows | Windows 10 | Windows 11 + MSYS2 |
必要依赖安装
在Ubuntu系统上安装编译依赖:
sudo apt-get update
sudo apt-get install -y \
build-essential \
qt5-default \
qttools5-dev-tools \
libqt5webkit5-dev \
libqt5svg5-dev \
qtmultimedia5-dev \
libssl-dev \
libfontconfig1-dev \
libfreetype6-dev \
git
中文字体文件准备
推荐字体选择
| 字体名称 | 特点 | 适用场景 | 许可证 |
|---|---|---|---|
| 思源黑体 | 开源、多字重、清晰易读 | 正文文本 | OFL |
| 思源宋体 | 开源、适合长文本阅读 | 文档正文 | OFL |
| 方正黑体 | 笔画均匀、专业感强 | 标题、重点内容 | 免费商用 |
| 微软雅黑 | Windows系统常用 | 通用场景 | 需要授权 |
字体文件获取与存放
- 创建字体存放目录:
mkdir -p /data/web/disk1/git_repo/gh_mirrors/wk/wkhtmltopdf/fonts
- 下载或复制中文字体文件到该目录,建议包含以下文件:
- SourceHanSansCN-Regular.otf (思源黑体)
- SourceHanSerifCN-Regular.otf (思源宋体)
- simhei.ttf (黑体)
- simsun.ttc (宋体)
源代码修改
字体配置文件修改
- 创建字体配置文件:
touch /data/web/disk1/git_repo/gh_mirrors/wk/wkhtmltopdf/src/lib/fontconfig.hh
- 添加以下内容定义中文字体路径:
#ifndef FONTCONFIG_HH
#define FONTCONFIG_HH
#include <QString>
#include <QStringList>
class FontConfig {
public:
static QStringList defaultFontPaths() {
return QStringList()
<< "/usr/share/fonts"
<< "/usr/local/share/fonts"
<< QDir::homePath() + "/.fonts"
<< QString::fromUtf8("/data/web/disk1/git_repo/gh_mirrors/wk/wkhtmltopdf/fonts");
}
static QStringList preferredFonts() {
return QStringList()
<< "Source Han Sans CN"
<< "思源黑体"
<< "Source Han Serif CN"
<< "思源宋体"
<< "SimHei"
<< "黑体"
<< "SimSun"
<< "宋体";
}
};
#endif // FONTCONFIG_HH
修改字体加载逻辑
编辑src/lib/utilities.cc文件,添加字体路径设置:
// 在文件开头添加包含
#include "fontconfig.hh"
// 在适当位置添加字体路径设置代码
void setupFontPaths() {
QFontDatabase fontDB;
// 添加自定义字体路径
foreach (QString path, FontConfig::defaultFontPaths()) {
QDir dir(path);
if (dir.exists()) {
fontDB.addApplicationFontDirectory(path);
}
}
// 设置默认字体
QFont defaultFont;
foreach (QString family, FontConfig::preferredFonts()) {
if (fontDB.hasFamily(family)) {
defaultFont.setFamily(family);
break;
}
}
if (!defaultFont.family().isEmpty()) {
QApplication::setFont(defaultFont);
}
}
修改项目文件以包含字体资源
编辑wkhtmltopdf.qrc文件,添加字体资源:
<RCC>
<qresource prefix="/">
<!-- 已有的资源 -->
<!-- 添加字体资源 -->
<file>fonts/SourceHanSansCN-Regular.otf</file>
<file>fonts/SourceHanSerifCN-Regular.otf</file>
<file>fonts/simhei.ttf</file>
<file>fonts/simsun.ttc</file>
</qresource>
</RCC>
修改PDF生成设置
编辑src/lib/pdfsettings.cc文件,添加字体嵌入设置:
void PdfSettings::setupDefaults() {
// 已有的默认设置...
// 添加字体嵌入设置
this->embedFonts = true;
this->loadCustomFonts = true;
this->fontDpi = 96; // 设置合适的DPI值,确保字体渲染清晰
}
编译配置与执行
配置编译选项
创建编译目录并运行qmake:
mkdir -p build && cd build
qmake ../wkhtmltopdf.pro \
CONFIG+=release \
FONTCONFIG=yes \
FONTDIR=/data/web/disk1/git_repo/gh_mirrors/wk/wkhtmltopdf/fonts
执行编译
make -j$(nproc)
编译过程可能需要30分钟到1小时,具体取决于系统性能。
安装编译结果
sudo make install
安装完成后,可执行文件将被安装到/usr/local/bin/wkhtmltopdf。
字体配置与验证
命令行字体参数
wkhtmltopdf提供了多个与字体相关的命令行参数:
| 参数 | 说明 | 示例 |
|---|---|---|
| --dpi | 设置DPI值 | --dpi 96 |
| --default-header-font-name | 设置页眉默认字体 | --default-header-font-name "思源黑体" |
| --default-header-font-size | 设置页眉字体大小 | --default-header-font-size 10 |
| --footer-font-name | 设置页脚字体 | --footer-font-name "思源宋体" |
| --footer-font-size | 设置页脚字体大小 | --footer-font-size 10 |
创建测试HTML文件
创建一个包含多种中文字体样式的测试文件test.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>中文字体测试</title>
<style>
.source-han-sans { font-family: "Source Han Sans CN", "思源黑体"; }
.source-han-serif { font-family: "Source Han Serif CN", "思源宋体"; }
.simhei { font-family: "SimHei", "黑体"; }
.simsun { font-family: "SimSun", "宋体"; }
.custom-size { font-size: 16px; }
.bold { font-weight: bold; }
.italic { font-style: italic; }
</style>
</head>
<body>
<h1>中文字体测试页面</h1>
<div class="source-han-sans custom-size">思源黑体测试:这是一段使用思源黑体显示的文本。</div>
<div class="source-han-serif custom-size">思源宋体测试:这是一段使用思源宋体显示的文本。</div>
<div class="simhei custom-size">黑体测试:这是一段使用黑体显示的文本。</div>
<div class="simsun custom-size">宋体测试:这是一段使用宋体显示的文本。</div>
<div class="source-han-sans bold">思源黑体粗体:这是一段粗体文本。</div>
<div class="source-han-serif italic">思源宋体斜体:这是一段斜体文本。</div>
<div class="source-han-sans">中文标点符号测试:,。;:!?“”‘’()《》【】、</div>
<div class="source-han-sans">特殊字符测试:①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮</div>
</body>
</html>
生成PDF并验证
使用以下命令将测试HTML转换为PDF:
wkhtmltopdf --dpi 96 test.html test.pdf
检查生成的test.pdf文件,验证所有中文字体是否正确显示。
高级配置:自定义字体嵌入
方法一:通过CSS @font-face嵌入
@font-face {
font-family: 'MyCustomFont';
src: url('/path/to/custom/font.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
.custom-font {
font-family: 'MyCustomFont', sans-serif;
}
方法二:命令行参数指定字体
wkhtmltopdf \
--user-style-sheet custom.css \
--default-font-name "Source Han Sans CN" \
input.html output.pdf
方法三:修改默认字体配置
编辑/etc/fonts/local.conf文件,添加字体配置:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="pattern">
<test name="family"><string>sans-serif</string></test>
<edit name="family" mode="prepend" binding="strong">
<string>Source Han Sans CN</string>
<string>SimHei</string>
</edit>
</match>
<match target="pattern">
<test name="family"><string>serif</string></test>
<edit name="family" mode="prepend" binding="strong">
<string>Source Han Serif CN</string>
<string>SimSun</string>
</edit>
</match>
</fontconfig>
常见问题解决
问题1:字体仍然显示为方块
可能原因:
- 字体文件路径不正确
- 字体文件权限问题
- 字体格式不受支持
解决方法:
# 检查字体文件权限
chmod 644 /data/web/disk1/git_repo/gh_mirrors/wk/wkhtmltopdf/fonts/*
# 清除字体缓存
fc-cache -fv
# 验证字体是否被系统识别
fc-list | grep "Source Han"
问题2:部分特殊符号无法显示
解决方法:
- 确保使用的字体包含所需符号
- 添加后备字体:
.font-with-fallback {
font-family: "Source Han Sans CN", "SimHei", "WenQuanYi Micro Hei", sans-serif;
}
问题3:PDF文件体积过大
优化方法:
- 使用字体子集化:只嵌入文档中使用的字符
- 降低字体嵌入质量:
wkhtmltopdf --pdf-settings dpi=72 --image-quality 85 input.html output.pdf
自动化编译脚本
为简化编译过程,可以创建一个自动化脚本build_with_fonts.sh:
#!/bin/bash
set -e
# 字体目录
FONT_DIR="/data/web/disk1/git_repo/gh_mirrors/wk/wkhtmltopdf/fonts"
# 检查字体文件是否存在
required_fonts=(
"SourceHanSansCN-Regular.otf"
"SourceHanSerifCN-Regular.otf"
"simhei.ttf"
)
missing_fonts=()
for font in "${required_fonts[@]}"; do
if [ ! -f "$FONT_DIR/$font" ]; then
missing_fonts+=("$font")
fi
done
if [ ${#missing_fonts[@]} -ne 0 ]; then
echo "错误:缺少以下字体文件:"
for font in "${missing_fonts[@]}"; do
echo " - $font"
done
exit 1
fi
# 创建构建目录
mkdir -p build && cd build
# 配置编译选项
qmake ../wkhtmltopdf.pro \
CONFIG+=release \
FONTCONFIG=yes \
FONTDIR="$FONT_DIR"
# 编译
make -j$(nproc)
# 安装
sudo make install
# 验证安装
if command -v wkhtmltopdf &> /dev/null; then
echo "编译安装成功!版本信息:"
wkhtmltopdf --version
else
echo "安装失败,未找到wkhtmltopdf命令"
exit 1
fi
添加执行权限并运行:
chmod +x build_with_fonts.sh
./build_with_fonts.sh
总结与展望
本文详细介绍了编译支持中文字体的wkhtmltopdf的完整流程,包括:
- 理解wkhtmltopdf字体渲染原理
- 准备编译环境和中文字体文件
- 修改源代码以支持中文字体集成
- 执行编译并验证结果
- 高级配置和常见问题解决
通过这些步骤,你可以构建一个完全支持中文字体的wkhtmltopdf版本,满足各种中文文档转换需求。
未来,随着wkhtmltopdf的不断更新,字体支持可能会更加完善。建议定期关注项目的官方更新,并及时同步最新的字体配置方法。
如果你在实施过程中遇到任何问题,欢迎在评论区留言讨论,或参考项目的GitHub仓库获取最新信息。
相关资源
- wkhtmltopdf官方文档:https://wkhtmltopdf.org/docs.html
- QtWebKit字体渲染文档:https://doc.qt.io/qt-5/qtwebkit-index.html
- 思源字体官方网站:https://source.typekit.com/source-han-sans/cn/
- Fontconfig配置指南:https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



