news 2026/9/30 8:25:32

打印表格字体变异排查与实战:@media print字体回退与样式修复指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
打印表格字体变异排查与实战:@media print字体回退与样式修复指南

1. 问题现场:一张表格从屏幕到纸张的“变形记”

1.1 用户看到的是“字体变异”,我看到的是另一个世界

上个月在维护一个内部报表系统的时候,我突然被一条语音炸到了。用户一边发消息一边拍屏幕说:“屏幕上面明明好好的,一点打印,表格里的字全变了,像被别人换过字体一样。”刚开始我还以为是常规的“没截图好”或者“选错打印机”,但等他把保存出来的 PDF 截图发过来时,我也愣了一下。

页面标题部分还是正常的黑体/微软雅黑,表格区域的中文却变成“像宋体又不完全是宋体”的样子,英文字母和数字全部切换成类似 Times New Roman 的衬线体。更诡异的是,表格里有的字变浅了,有的字变细了,表头背景色全部消失,连列宽都和屏幕上差了一大截。用户说得挺形象:不是打印坏了,而是“字体被偷偷换了一版”。

这种问题在后台管理系统里非常容易遇到,尤其是和报表、订单、结算相关的页面。原因也远没有“CSS 写错”这么简单——它其实是浏览器在屏幕渲染和打印渲染两个完全不同的光栅化环境里,对字体、颜色、背景、宽度分别做出不同决策的连锁反应。换句话说:没有真正变异的字体,只有不止一套的字体回退和渲染策略。

这篇文章记录的就是我对这个问题的完整排查过程和最终落地方案,适合正在维护老系统、遇到打印字体异常、或者打算给项目加打印/PDF导出功能的朋友直接参考。我不敢保证看完之后你的打印一定完美,但至少能让你知道该查哪里、该怎么改。

1.2 先分清三件事:字体被换、渲染变暗、还是排版重排

我在接到这种打印类报障后的第一件事,不是打开代码,而是先问自己三个问题:

  1. 字体是不是真的被换成了另一个字体族?
  2. 字体其实没换,只是颜色、粗细、抗锯齿方式变了,导致看起来像另一款字?
  3. 表格排版因为打印纸张宽度发生了重排,列宽、换行全变了,视觉上给人“字体也变了”的错觉?

这三个问题不先分清,后面很容易走弯路。比如“字体变浅”这件事,很多时候根本不是字体问题,而是打印引擎默认不输出背景色,导致原先依赖背景衬托的白色文字或灰色文字失去对比度,看起来像字体残缺。再比如“字体变窄”,有可能只是表格从屏幕的自适应宽度切换到了固定纸张宽度,单元格内容被换行,原来的数字对不齐了。

我把这类问题归成一个原则:凡是“打印和屏幕不一致”的报障,先怀疑字体回退,再怀疑颜色与背景,最后怀疑表格布局。下面几节就按这个顺序展开。

2. 为什么@media print下table的字体说变就变

2.1 字体回退是幕后黑手:font-family只是候选名单

很多朋友对 CSS 里font-family的理解是“我指定了哪个,浏览器就用哪个”,这个理解在大方向上没错,但实际执行时要打不少折扣。浏览器拿到字体列表后,不是“选中第一个就完事”,而是会依次检查:这个字体在当前系统里装没装?加载完没有?当前字符集里能不能覆盖到我要显示的那些字符?

比如这段常见的字体声明:

body { font-family: "PingFang SC", "Microsoft YaHei", "Helvetica Neue", sans-serif; }

在 Windows 的 Chrome 屏幕渲染下,大概率会选择“微软雅黑”;在 macOS 上会优先选“苹方”;但如果系统里都没有,就会继续往下走,直到命中最后一个无衬线通用族,由浏览器再决定用它的默认无衬线字体。注意,这个“浏览器默认字体”是可以被用户手动修改的,并不是某个恒定不变的字体。

令人头大的是,打印环境的默认值和屏幕环境经常不一样。你在屏幕上看到的是一种回退结果,进入打印/PDF 生成流程后,由于打印引擎、PDF 生成器、系统字库三方参与决策,最终生效的字体很可能是另一个候选。

我之前见过一个特别典型的例子:某系统在某台 Windows 电脑上屏幕显示一切正常,打印后表格里的中文全部变成“宋体”,英文变成“Times New Roman”。查到最后,页面样式里写的是font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif。这种写法在 macOS 上非常漂亮,在 Windows 屏幕上会命中“Segoe UI”,但这份字体里本身没有中文字形。屏幕阶段浏览器的字体回退策略会额外找到系统中文字体去补足缺字,看起来还是舒服的;可打印阶段一旦字体内嵌失败或回退路径不同,就会直接落到系统默认的宋体/衬线体上。于是,你觉得“预览还好”,打印出来却变了。

所以我的第一个建议很直白:如果某个页面的打印结果非常重要,请不要把字体声明全部交给通用字体族去兜底。你必须明确写出目标平台存在的字体,并且把中文字体排在足够靠前的位置。

2.2 打印引擎、PDF生成器与系统字库的“三方会诊”

字体“变异”的第二个原因是现代打印流程太复杂。你点下 Ctrl+P 之后,并不是“屏幕内容直接进打印机”,而是要经历:页面排版 → 打印光栅化 → 生成打印指令或 PDF → 打印机驱动/硬件解释这一长串环节。

这里有两个容易踩坑的点。

第一个是 PDF 的字体嵌入机制。浏览器在“另存为 PDF”时,通常会把页面用到的字体子集嵌进 PDF 文件。但如果某个字体因为许可证限制、加载不完整、或者生成 PDF 的组件不支持该字体格式,PDF 里的字就不会按“完整字库”嵌入,而只是记录一个字体名字,等阅读器或打印机在本地找同名字体来替换。本地没有同名字体时,阅读器就会使用自己内置的默认字体顶上。于是你看到的就是“字体被换了个面目”。

第二个是系统字库参与替换。以中文环境为例,一个 Windows 系统里可能装了宋体、黑体、仿宋、楷体、微软雅黑等一堆字体;而一台 Linux 服务器或嵌入式终端上可能只装了少数几个 CJK 字体。页面在 Windows 上打印时,系统字库还能兜住基本盘;一旦部署到缺字库的 Linux 环境,通过无头浏览器生成 PDF 时,中文字就很容易变成“豆腐块”或方框。

这类问题在线上报表系统里尤其隐蔽,因为开发机上有字体,服务器上没有。解决方向有两个:一是在部署环境里补装常用中文字体,比如 Linux 下安装fonts-noto-cjk、fonts-wqy-microhei之类;二是在页面字体栈里提供足够多的回退选择,同时接受“不同环境下打印结果会有细微差别”这个现实。

2.3 table在打印介质里不是“你看到的那张表”

为什么这个问题偏偏在 Table 上特别明显?因为表格是对排版变化最敏感的元素之一。

屏幕上表格的可用宽度是浏览器窗口宽度,可能是 1920px,也可能是 1366px;而打印时可用宽度是纸张宽度减去页边距,通常只有 180mm 左右。浏览器在打印阶段会把整个页面重新排一遍,此时表格的table-layout: auto会按照每个单元格的最小/最大内容宽度重新分配列宽。

也就是说,哪怕字体一个都没换,只要页面变窄,表格列宽重新分配,字数多的列就会被压缩,单元格里的文本开始换行。原来的“序号+名称+金额”整整齐齐三列,打印出来变成“序号”列不到 1cm,名称列撑得很宽,金额被折成两行。用户看到这种变化,第一反应往往是“字体不对”,但其实真正的问题是排版重排。

更麻烦的是,现代 UI 框架在做表格时经常会给th、td直接指定font-family: -apple-system, ...或font-size: 13px。这些选择器的优先级可能高于你写在body或打印样式里的规则,导致你在@media print里设置了半天字体,表格就是不生效。

我在这里先给一个结论:打印表格,不要只改body,必须把table/th/td这些元素单独拉出来再声明一次。至于具体写法,第四章会给出完整可抄的代码。

2.4 颜色丢失与低对比度:字体并不是变浅了,而是“看不见了”

还有一个被低估的因素:打印引擎默认不输出背景色。

Chrome、Firefox、Safari 在打印时都有一个类似“背景图形”的开关。默认情况下,元素的background-color、background-image在打印输出里会被忽略。这就导致很多屏幕设计里对比度良好的文字,到了纸张上变得非常难读。

举个例子:表格的表头是深蓝色背景、白色文字,内容区是浅灰色背景、灰色文字。打印出来后,深蓝背景没了,白字变成纯黑;浅灰背景没了,灰字的浅色在黑白打印里几乎看不清。用户只会觉得“字体怎么变淡了、变了”,实际是颜色对比度被整个打平了。

这个问题和字体渲染也有关联。屏幕上的文字用了亚像素抗锯齿和 ClearType 技术,看起来边缘平滑;打印时是按照 300dpi 甚至更高分辨率重新光栅化,文字边缘更硬。加之上面的颜色丢失问题,文字观感就完全不一样了。要解决,必须显式告诉浏览器“按精确颜色输出背景和前景”,也就是用到print-color-adjust属性,后面我会具体展开。

3. 我如何定位这次字体“变异”:完整排查链路

3.1 用打印模拟器把问题环境搬到开发台

别一上来就反复按 Ctrl+P 看打印预览,那个过程又慢又容易看漏。Chrome 和 Edge 的 DevTools 里都有“渲染”面板,里面有一个Emulate CSS media type选项,可以直接切换到print媒体类型。

具体路径是:按 F12 打开开发者工具 → 在顶部找到“渲染 Rendering”标签,如果没看到,点右上角的“更多工具” → 选择“渲染” → 在“Emulate CSS media type”里改成print。

切换之后,整个页面会立即按打印媒体的 CSS 规则重新计算样式。这时候你再检查getComputedStyle(document.body).fontFamily,或者在 Elements 面板里选中某个表格单元格,看它的 Computed 样式里最终生效的字体系列是什么。这个操作能帮你快速判断:问题到底是样式规则本身没覆盖到,还是字体缺失导致的回退。

我排查那次问题时,就是用模拟器先确认了表格单元格里 computed font-family 其实还挂着“Microsoft YaHei”,但浏览器实际用的是什么字体,预览里看不出来。这一步至少帮我把“CSS 没生效”这个可能性排除了,接下来才能往字体回退方向查。

3.2 看生成PDF的字体列表,而不是看预览

字体是否真的被替换,最可靠的判定方式是直接看生成的 PDF 文件里嵌入了哪些字体。

我在打印对话框里选择“另存为 PDF”后,用支持查看字体列表的 PDF 阅读器打开这个文件,在文档属性/字体标签页里能看到类似“Microsoft YaHei”“SimSun”“Liberation Serif”这样的列表。如果表格区域实际渲染字体不是你所期望的,这里的记载基本就是你真正的“案发现场”。

当时我看到的情况是:页面顶部标题用的字体是“Microsoft YaHei”,表格里却出现在“SimSun”和“Liberation Serif”。这就说明浏览器在打印时放弃了目标字体,选择了系统中文字体回退方案。原因大概率是表格单元格里的样式声明优先级覆盖了 body 上的字体,导致表格区域走了另一条字体匹配路径。

这里也提醒一句:PDF 字体列表并不总能反映最终打印出来的物理效果。如果用户直接把打印任务发给打印机,中间还夹着打印机驱动和硬件固件的字体替换。但“看 PDF 字体列表”仍然是定位第一步最有效的手段。

3.3 px、pt与实际字号:为什么打印出来的字就是觉得“变小了”

在排查过程中,我还发现很多“字体变异”其实是字号导致的错觉。屏幕上的 CSSpx和打印领域的pt是不同的单位,它们之间有换算关系:在 CSS 2.1 的定义里,1in = 96px = 72pt,也就是说 16px 约等于 12pt。

很多管理系统为了屏幕显示紧凑,正文用 12px、13px,表头用 14px。这些尺寸在屏幕上看着没问题,打印到 A4 纸上会给人偏小的感觉。如果打印样式里没有重新定义字号,浏览器会直接按 96dpi 的假定换算到物理尺寸,结果就是你觉得“屏幕上 14px 的字不算小,怎么打印出来这么小”。

解决办法不是简单地把所有字号调大,而是在@media print里按照纸张阅读习惯重设基准字号。我一般把正文设置成 12pt,表格内容 10pt 到 10.5pt,表头加粗到 11pt。这个尺寸在 A4 上接近日常文档排版,阅读会比较舒服。

3.4 字体缺失、字体冲突与中文环境的“隐藏炸弹”

排查到这一步,我已经确定是表格区域触发了字体回退,但为什么 Screen 上没有回退?这里就要说到中文环境特有的字体问题了。

同一个中文文字可能对应好几个字体名:宋体、中易宋体、SimSun、NSimSun、宋体-简、DengXian、等线、霞鹜文楷……不同系统、不同来源的同名字体,实际字形设计还不完全一样。比如“仿宋_GB2312”和“仿宋 GBK”用在公文里视觉效果差异明显;“霞鹜文楷”这类开源字体如果只装在开发机,没装到用户的机器上,打印时就会直接回退。类似“字体冲突”“字体下载”的搜索热度一直很高,说明这不是个别人遇到的问题。

更麻烦的场景是服务器环境。有很多中后台项目会在服务端用 Puppeteer、Playwright、wkhtmltopdf 之类生成 PDF。这些无头浏览器运行在 Linux 服务器上时,系统里几乎没有微软雅黑、宋体这类字体。如果项目 CSS 里写的字体全是 Windows 字体名,生成出来的 PDF 里中文就全变成了豆腐块,或者被替换成一个极其难看的缺字字形。这就是“麒麟系统字体下载”“Linux 系统安装 WPS 缺少字体”这些热词背后真实发生过的坑。

碰到这种情况,我通常会做两手准备:第一,服务器上安装必要的 CJK 字体包,至少保证Noto Sans CJK SC、WenQuanYi Micro Hei这类开源中文字体存在;第二,把字体栈写成“先商用字体、后开源字体、再通用字体”的形式,并且把这些字体名写进打印样式的table规则里。

4. 一份能直接抄走的Table打印字体修复方案

4.1 先给打印环境立规矩:font-family基线要在table上再写一遍

说了这么多原理,现在给一套可以落到项目里的完整方案。核心思想很简单:在@media print里给打印环境重新建立一套明确的默认规则,尤其是把表格元素单独覆盖一遍。

@media print { @page { size: A4; margin: 12mm; } body { font-family: "Noto Sans CJK SC", "Source Han Sans SC", "Microsoft YaHei", "PingFang SC", "WenQuanYi Micro Hei", sans-serif; font-size: 12pt; line-height: 1.5; color: #000; background: #fff; } table, thead, tbody, tr, th, td { font-family: inherit; font-size: 10pt; color: #000; background: #fff; } }

这里有两个细节需要注意。

第一,为什么用font-family: inherit?是因为很多 UI 框架会在th、td上直接写类似font-family: -apple-system, "Segoe UI", sans-serif的规则。inherit在这里能强制让表格元素继承你在body上声明的字体栈。但说实话,inherit在某些框架的高优先级选择器面前也可能不保险,更稳妥的做法是直接把这个完整的字体栈再抄一遍到表格规则里,必要时加!important。

第二,不要只设置body。打印表格时,th、td本身也是独立的字体上下文,浏览器不会无条件从body继承。尤其是复用组件库的场景,组件内已经定了字体,光改body是无效的。把这套规则写成一个独立的print.css,用<link rel="stylesheet" media="print" href="print.css">引入,平时不加载,打印时自动生效,管理起来也清爽。

4.2 让表格背景色、边框与斑马纹真正出现在纸上

表格要打印得清晰,除了字体,背景和边框也要显式声明。

@media print { * { -webkit-print-color-adjust: exact; print-color-adjust: exact; } table { width: 100%; border-collapse: collapse; table-layout: fixed; } th, td { border: 1px solid #000; padding: 5pt 6pt; vertical-align: middle; } thead th { background-color: #333 !important; color: #fff !important; font-weight: 700; } tbody tr:nth-child(even) td { background-color: #f2f2f2 !important; } }

-webkit-print-color-adjust: exact和print-color-adjust: exact是让浏览器按照页面里写的颜色原样输出背景,而不是默认省墨。Chrome/Edge 对这个属性的支持是有的,Firefox 近年也跟上了,但不同打印机驱动表现仍有差异。如果还不行,备选方案是用box-shadow模拟斑马纹,或者干脆把深色表头改成白底黑字加粗、黑色边框,这样即使背景色丢失,表格也不至于失去可读性。

要特别注意:打印的表格尽量用真实<table>元素。如果项目里是 div + flex 模拟的表格,浏览器在分页时无法判断哪些行属于同一表格,也无法在跨页时自动重复表头。打印这块,原生 table 依然是最靠谱的方案。

4.3 跨页断行、表头重复和列宽失控问题

字体修复完,第二个高频问题就是表格跨页。表格太长,一页放不下时,打印结果会把一个<tr>从中间切开,或者表头不重复,第二页开始就是一堆没有表头的数据,读者根本不知道每列是什么。

对应解决方案如下:

@media print { thead { display: table-header-group; } tr, th, td { page-break-inside: avoid; break-inside: avoid; } tbody tr { page-break-after: auto; } td, th { word-wrap: break-word; overflow-wrap: break-word; } }

display: table-header-group的作用就是告诉浏览器:跨页时请自动重复 thead 的内容。这本来是原生 table 的默认行为,但很多框架的 reset 样式会把thead的 display 改成block或contents,导致重复失效,所以要在打印样式里重新指回来。

列宽失控的应对方案是table-layout: fixed。固定布局下,列宽主要由表格宽度和第一行单元格宽度决定,不会再根据内容自适应。这个属性可以让打印表格在纸张宽度范围内更稳定。如果有特殊列,可以在表格里配合<colgroup>指定每列宽度,例如第一列 20mm、第二列 60mm、第三列 40mm 这样。我个人的习惯是:凡是需要打印的报表,业务开发时就固定列数,过多的列要么合并,要么拆成多张表,尽量不要在 A4 宽度里塞 8 列以上。

4.4 需要网页字体时:预加载、子集与base64怎么选

如果你的项目使用了网页字体,比如开源字体“霞鹜文楷”(LXGW WenKai)、思源黑体或思源宋体,打印时也要考虑加载时序。浏览器只有在字体加载完成后才会用该字体渲染,如果用户打开页面后立刻点打印,字体还没加载完,打印任务就会使用回退字体,形成“这次打出来是对的,下次打出来又变了”的随机现象。

解决这个问题的办法有三个思路:

第一个思路:打印前等待字体加载。如果项目里有自定义打印按钮,可以在弹出打印对话框前用await document.fonts.ready等待字体加载完成,再调用window.print()。至少能把“过早打印”的概率降下来。

第二个思路:用子集字体。中文字体动不动几 MB 甚至十几 MB,直接做网页字体确实负担重。如果只是打印少量固定文案,可以对字体做子集抽取。像fonttools里就有pyftsubset工具,可以把字体里用不到的几千个汉字去掉,只保留业务需要的几百个字,生成 woff2 后体积可以压缩到很小。

pyftsubset SourceHanSansCN-Regular.otf \ --text-file=chars.txt \ --flavor=woff2 \ --output-file=print-font-subset.woff2

第三个思路:base64 内联到 CSS。在@media print里把子集字体文件转成 base64,直接写进@font-face的src: url(data:font/woff2;base64,...)。这样做能让打印 CSS 完全自包含,不依赖网络请求。缺点是可以维护的复杂度变高,字体更新时 CSS 也要跟着更新。所以我只在打印样式相对稳定的项目里用这个方案。

说实话,对于绝大多数管理系统,我更倾向于不使用网页字体来承载正文,而是找一个系统中大概率存在的黑体/宋体类字体作为主力,把网页字体只用于标题或 logo。打印场景里“稳定可预测”比“精致好看”重要得多。

5. 不同浏览器和平台的打印行为差异,以及最后的选择

5.1 Chromium系与Firefox的差异,别只看预览

Chrome 和 Edge 现在都是 Chromium 内核,在打印字体处理上大体一致,但 Firefox 有自己的排版和打印引擎,表现会有差别。

比较大的差异点在于背景色的打印。Chrome 在打印对话框里有一个“背景图形”复选框,需要用户手动勾选,或者页面显式设置print-color-adjust: exact;Firefox 更保守,即使有了print-color-adjust,在某些版本里仍可能不输出背景。如果你服务的用户群体里 Firefox 占比不低,我的建议是:打印样式里不要过度依赖背景色来表达关键信息。文字颜色、边框粗细、加粗这些才是跨浏览器稳定可靠的信号。

另外注意,浏览器里的打印预览往往只是“接近最终效果”,不代表打印机最终输出。预览用的是屏幕渲染加模拟分页;真实打印还会经过打印驱动。所以别把打印预览当成验收标准,最靠谱的做法是生成 PDF 后在不同阅读器里各看一遍。

5.2 手机端、WebView和“小册子/自定义纸张”的额外坑

这套问题在手机浏览器和 WebView 里会更夸张。iOS 上的 Safari 打印通常不嵌入网页字体,中文字体交互时经常退化成系统默认字体;Android 上不同厂商的打印服务行为也不同,用户选择“另存为 PDF”时,生成的 PDF 可能和你预期的完全不一样。

如果你的用户有“把页面打印成小册子”的需求,比如设置 A4 打印在 A3 上、双面打印、多页拼版,这类能力高度依赖打印对话框里的设置和打印机驱动。网页 CSS 能控制的是分页位置、页面尺寸、页边距,但控制不了用户选择的纸张规格和装订模式。你能做的最好的事情,就是保证表格在 A4 纵向模式下不会因为宽度溢出而被迫缩放。

如果你在 Windows 上遇到“系统打印服务已关闭”或“0x00000bbb 无法创建打印作业”这类系统级错误,那就不是页面 CSS 的事了。先把打印队列清空,把 Print Spooler 服务重启,再让用户重试。系统层的问题不用归到字体头上。

5.3 什么时候放弃浏览器打印,改用脚本化PDF

如果你已经把所有 CSS 调了一遍,还是搞不定,那就该考虑换一条路:放弃“浏览器打印按钮”,改用无头浏览器脚本化生成 PDF。

部署一个基于 Puppeteer 或 Playwright 的导出服务,在服务端打开页面、等页面稳定、模拟print媒体类型、直接产出 PDF 文件,再把文件交给用户。这样做至少把“打印结果可预测”这一步握在自己手里。

Puppeteer 的基本步骤大概是这样的:

const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto(url, { waitUntil: 'networkidle0' }); await page.emulateMediaType('print'); await page.pdf({ path: 'report.pdf', printBackground: true, preferCSSPageSize: true, }); await browser.close();

这个方案不是万能的。第一,服务器上必须安装好中文环境字体,否则page.pdf输出依然会是豆腐块。第二,前端页面如果依赖大量异步接口或图表,等待时机设置不好就会导出半成品。但相对“用户在自己电脑上随便一打印”来说,脚本化导出的可控性已经高很多。

如果公司内部还要求把导出 PDF 接进审批流、邮件附件,那这种服务化的方式几乎是唯一出路。浏览器打印只适合“用户自己操作、自己确认”的场景,不适合自动化流水线。

6. 把“怪异变异”挡在发布前的排错清单

最后分享一个我现在一直在用的排错清单。每次遇到“浏览器打印字体变了”的报障,我按这个顺序做,基本上能在二十分钟内定位到问题。

  1. 先看系统环境:用户是 Windows、macOS、Linux?浏览器是 Chrome、Edge、Firefox?打印用的是具体打印机还是“另存为 PDF”?
  2. 在 DevTools 里切换Emulate CSS media type: print,看表格单元格 computed font-family 是否符合预期。
  3. 把打印结果保存为 PDF,在支持查看字体的阅读器里打开,检查实际嵌入字体列表。
  4. 区分原因:字体被替换?字号和单位换算导致观感不对?背景颜色丢失导致对比度失效?还是表格列宽重排导致视觉变化?
  5. 如果是字体替换:检查 font-family 栈是否足够完整、目标字体在目标系统是否存在、网页字体是否已经加载完成。
  6. 如果是颜色问题:补上print-color-adjust: exact,并且让表格不要依赖“浅底浅字”的组合。
  7. 如果是表格布局问题:设置table-layout: fixed,调整列宽和字号,加入跨页重复表头规则。
  8. 如果服务器端生成 PDF 乱码:先装字体,再查业务代码里是不是写死了 Windows 字体名。
  9. 如果用户机器上出现打印队列、驱动、系统打印服务相关报错,先解决系统打印服务,再谈页面样式。

这些步骤里,最实用的一条其实是:把每一次你验证过、有效的打印样式沉淀成一个print.css模板,下次直接复用。我现在的习惯是,凡是涉及表格打印的新页面,上线前都会先用“另存为 PDF”走一遍导出流程,再用一台没有安装业务字体的测试机复测一次。这两步能过滤掉绝大多数“字体诡异变异”的问题。

说句实在话,跨端打印能做到 100% 和屏幕完全一致几乎不现实,因为屏幕和纸张本来就是两种媒介。我们能追求的目标,是让打印结果稳定、清晰、不出错。只要掌握了字体回退、颜色输出、表格布局这三条主线,再诡异的“字体变异”也不至于让你半夜加班加到头秃。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 8:25:02

Apache Doris是什么?从架构到选型,一文讲透实时OLAP数据库

先想一个特别真实的问题&#xff1a;你手里的表&#xff0c;已经不只是几千行数据了。每天有上亿条访问日志往里面灌&#xff0c;老板随时要按渠道、按商品、按省份拉多维汇总&#xff0c;还要能钻取到底层明细。MySQL扛不住这种量级的聚合查询&#xff0c;跑一次全表扫描能卡几…

作者头像 李华
网站建设 2026/9/30 8:24:07

华为Eudemon防火墙从接口IP到ACL包过滤完整配置链路

简介&#xff1a;这是一份聚焦华为Eudemon防火墙配置的实操型资料&#xff0c;面向网络工程师、企业IT运维及华为安全技术学习者&#xff0c;解决从接口接入、路由打通到安全策略落地的典型配置需求。文档以Eudemon连接Trust、DMZ与Untrust三个安全区域为场景&#xff0c;完整覆…

作者头像 李华
网站建设 2026/9/30 8:24:01

MySQL的数据类型

bit::Shadow✧(≖ ◡ ≖✿ 目录 int类型 bit 浮点数 float decimal 字符串类型 char varchar char VS varchar 日期、时间类型 格式 时间戳一定是自动改变的吗&#xff1f; enum与set 在set列中怎么插入多个值呢&#xff1f; 插入时的底层 enum set 举例 类型…

作者头像 李华
网站建设 2026/9/30 8:21:57

大模型落地企业数字化转型:技术选型、架构设计与避坑指南

简介&#xff1a;《大模型与企业数字化转型解决方案》PPT是一份面向企业中高层管理者、数字化转型负责人及技术人员的系统化参考材料&#xff0c;聚焦大模型技术如何落地到企业业务场景&#xff0c;帮助解决转型过程中的技术选型、架构规划与组织协同难题。压缩包内为1个PPT文件…

作者头像 李华