.NET 5.0 XSLT转PDF时FONetXslFOPdfRenderer特殊字符异常怎么解决
问题根因
你遇到的特殊字符被替换为#的问题,核心是FONet渲染PDF时使用的默认内置字体仅支持基础ASCII字符集,不支持ć这类扩展拉丁字符,和XML、XSLT的编码配置无关,你的编码环节已经正常完成,问题出在PDF渲染阶段的字体匹配逻辑。
解决方案步骤
第一步:准备兼容字体
选一款覆盖你所需特殊字符的字体文件(如Arial Unicode MS、思源黑体等),将.ttf/.otf格式的字体文件放到项目资源目录下,设置文件属性的「复制到输出目录」为「如果较新则复制」。第二步:修改XSL样式表配置
在你的XSL文件中新增全局字体声明,指定所有文本使用你准备的兼容字体,参考配置如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:output method="xml" encoding="utf-8" indent="yes"/> <!-- 全局字体配置 --> <xsl:template match="/"> <fo:root> <fo:layout-master-set> <!-- 此处保留你原有的页面布局配置 --> </fo:layout-master-set> <fo:page-sequence master-reference="YourMasterPage"> <!-- 给根flow节点设置font-family,所有子节点会继承该配置 --> <fo:flow flow-name="xsl-region-body" font-family="Arial Unicode MS"> <!-- 此处保留你原有的内容渲染逻辑 --> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> </xsl:stylesheet>
- 第三步:修改C#渲染配置,新增字体目录映射
修改你实例化XslFOPdfOptions的代码,添加字体文件所在目录的配置,让FONet可以找到你引入的兼容字体,参考代码如下:
XDocument xmlDoc = XDocument.Load("myXml.xml"); XDocument xslt = XDocument.Load("myXSL.xsl"); XsltArgumentList args = new XsltArgumentList(); string str = XmlLinqXsltExtensions.Transform(xmlDoc, xslt, args); File.WriteAllText("foStr.xml",str); XslFOPdfOptions xslFoPdfOptions = new XslFOPdfOptions(); xslFoPdfOptions.EnablePrinting = true; // 新增字体目录配置,替换为你实际存放字体文件的目录路径 xslFoPdfOptions.FontDirectories = new List<string> { Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts") }; // 修正原代码多余的括号问题 FONetXslFOPdfRenderer foNetXslFoPdfRenderer = new FONetXslFOPdfRenderer(XDocument.Load("foStr.xml"), xslFoPdfOptions); byte[] bytes = foNetXslFoPdfRenderer.RenderPdfBytes(); outputStream.Write(bytes, 0, bytes.Length);
- 第四步:验证生效
重新运行转换流程,如果还是出现#号,先检查字体文件是否正确复制到了输出目录,再确认你使用的字体是否确实包含对应特殊字符(可以通过系统字体查看器打开字体文件,搜索对应字符确认是否存在)。
注意:如果项目用于商业用途,请确认你使用的字体具备对应的商业使用授权。
内容的提问来源于stack exchange,提问作者jahuer1
相关产品推荐
相关产品推荐

