为有中文需求的客户提供多渠道中文技术支持.

Fri Sep 05, 2025 12:35 am

您好, 我在docker下使用.netstandard2.0 DLL 测试下面的代码, 甜蜜早安吻字体的中英文显示正常, 而Microsoft YaHei Mono字体的中文显示乱码! 应该是没识别到字体 (在spire.Doc组件中这两个字体的设置和显示是正常的, 能正确识别到)
Code: Select all
using System;
using System.IO;
using System.Drawing;
using Spire.Pdf;
using Spire.Pdf.Graphics;

// Spire.Pdf
var pdf = new PdfDocument();
var page = pdf.Pages.Add();
// var standardFont = new PdfFont(PdfFontFamily.TimesRoman, 12f); page.Canvas.DrawString("Hello China, 你好 中國", standardFont, PdfBrushes.Black, new PointF(10, 10));
// var cjkFont = new PdfCjkStandardFont(PdfCjkFontFamily.HeiseiMinchoW3, 12f); page.Canvas.DrawString("你好 中國", cjkFont, PdfBrushes.Black, new PointF(10, 50));
var trueTypeFont = new PdfTrueTypeFont("甜蜜早安吻", 12f, PdfFontStyle.Regular, true); page.Canvas.DrawString("Hello China, 你好 中国!", trueTypeFont, PdfBrushes.Black, new PointF(10, 30));
var trueTypeFont2 = new PdfTrueTypeFont("Microsoft YaHei Mono", 12f, PdfFontStyle.Regular, true); page.Canvas.DrawString("Hello China, 你好 中國!", trueTypeFont2, PdfBrushes.Black, new PointF(10, 50));

pdf.SaveToFile("Spire.Pdf.pdf", Spire.Pdf.FileFormat.PDF);
Console.WriteLine("Spire.Pdf create!");


效果如下:
zz.png


在windows下, 同样使用.netstandard2.0 DLL, 在linqpad下测试, 效果相反: 甜蜜早安吻字体的中文显示乱码, 而Microsoft YaHei Mono字体好像也不正常!
效果如下:
xx.png


下面是docker容器内的字体列表:
/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf: DejaVu Sans Mono:style=Book
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK SC:style=Bold
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK TC:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK JP:style=Bold
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK HK:style=Bold
/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc: Noto Serif CJK KR:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK JP:style=Regular
/usr/share/fonts/truetype/custom/甜蜜早安吻.ttf: TMZAW,甜蜜早安吻:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK HK:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK KR:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK SC:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK TC:style=Regular
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK SC:style=Regular
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK TC:style=Regular
/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK JP:style=Regular
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK KR:style=Regular
/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc: Noto Serif CJK HK:style=Regular
/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf: DejaVu Sans Mono:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK TC:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK SC:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK KR:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK HK:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans Mono CJK JP:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK SC:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK TC:style=Regular
/usr/share/fonts/truetype/custom/Microsoft-YaHei-Mono.ttf: Microsoft YaHei Mono:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK HK:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK KR:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans Mono CJK JP:style=Regular
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK JP:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK KR:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK HK:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK TC:style=Bold
/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc: Noto Sans CJK SC:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf: DejaVu Serif:style=Book

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Fri Sep 05, 2025 2:06 am

docker下执行下面的Spire.Presentation代码, 第一次执行会报后面的错误, 第二次再执行就好了, 生成的文件中的字体效果也是对的

Code: Select all
using SkiaSharp;
using System;
using System.IO;
using System.Drawing;

//Spire.Presentation
var presentation = new Spire.Presentation.Presentation();
var slide = presentation.Slides[0];
// 第一个文字框
var shape1 = slide.Shapes.AppendShape(Spire.Presentation.ShapeType.Rectangle,
    new RectangleF(50, 50, 200, 50)); // 调整 x=50 以避免贴边
shape1.ShapeStyle.LineColor.Color = Color.White;
shape1.Fill.FillType = Spire.Presentation.Drawing.FillFormatType.None;
shape1.AppendTextFrame("Spire.Presentation! 你好, 中国!");
var textRange1 = shape1.TextFrame.TextRange;
textRange1.Fill.FillType = Spire.Presentation.Drawing.FillFormatType.Solid;
textRange1.Fill.SolidColor.Color = Color.Black;
textRange1.LatinFont = new Spire.Presentation.TextFont("甜蜜早安吻");
textRange1.EastAsianFont = new Spire.Presentation.TextFont("甜蜜早安吻");
// 第二个文字框
var shape2 = slide.Shapes.AppendShape(Spire.Presentation.ShapeType.Rectangle,
    new RectangleF(50, 150, 200, 50)); // 下移到 y=150,避免重叠
shape2.ShapeStyle.LineColor.Color = Color.White;
shape2.Fill.FillType = Spire.Presentation.Drawing.FillFormatType.None;
shape2.AppendTextFrame("hello, world, 你好, 世界!");
var textRange2 = shape2.TextFrame.TextRange;
textRange2.Fill.FillType = Spire.Presentation.Drawing.FillFormatType.Solid;
textRange2.Fill.SolidColor.Color = Color.Black;
textRange2.LatinFont = new Spire.Presentation.TextFont("Microsoft YaHei Mono");
textRange2.EastAsianFont = new Spire.Presentation.TextFont("Microsoft YaHei Mono");
presentation.SaveToFile("/output/Spire.Presentation.pptx", Spire.Presentation.FileFormat.Pptx2010);
Console.WriteLine("Spire.Presentation create!");



System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.InvalidOperationException: Cannot found font installed on the system.
at spr뢊.섦(String A_0, spr闢 A_1, String A_2)
at spr맖.銤(String A_0, Single A_1, spr闢 A_2, String A_3, spr闢 A_4)
at spr맖.銤(String A_0, Single A_1, spr闢 A_2, String A_3)
at spr맖.銤(String A_0, Single A_1, spr闢 A_2)
at spr☑..ctor(String A_0, Single A_1, spr闢 A_2, Boolean A_3)
at spr☑..ctor(String A_0, Single A_1, spr闢 A_2)
at spr칭.銤(Single A_0, Boolean A_1)
at spr칭.鎝(Single A_0)
at spr칭.饳()
at sprㅥ.鋷(String A_0, spr칭 A_1)
at sprㅥ.銤(鏰 A_0, 鏰 A_1, TextRange A_2, spr칭[] A_3)
at sprㅥ.銤(鏰 A_0, 鏰 A_1, TextRange A_2, Single& A_3, Single& A_4)
at sprㅥ.銤()
at sprㅥ..ctor(TextParagraphProperties[] A_0, ParagraphCollection A_1, Single A_2, Single A_3, Int32 A_4, Single A_5, Boolean A_6, TextAnchorType A_7, Boolean A_8, ActiveSlide A_9, 銤 A_10, LocaleFonts A_11, FontCollectionIndex A_12, Single A_13, Single A_14, Int32 A_15, Object A_16, spr㢇 A_17)
at spr㯅.銤(Single A_0, Single A_1, ShapeStyle A_2, spr㯅[] A_3, spr㢇 A_4)
at spr㎪.銤(GraphicFrame& A_0, RectangleF& A_1, Single& A_2, Single& A_3, Single& A_4, Single& A_5, spr㢇 A_6)
at spr㎪.閏()
at spr㎪.PptxPrepareForSaving(spr翄 saveContext)
at Spire.Presentation.Collections.ShapeList.銤(spr翄 A_0)
at Spire.Presentation.GroupShape.PptxPrepareForSaving(spr翄 saveContext)
at Spire.Presentation.ActiveSlide.PresentationBeforeSave(spr翄 saveContext)
at spr㗯.PresentationBeforeSave(spr翄 saveContext)
at spr㞎.銤(spr翄 A_0, spr❘ A_1)
at spr㞎.銤(Stream A_0, spr❘ A_1, spr㘔 A_2)
at spr㞎.銤(Stream A_0, spr㑵 A_1, spr㓈 A_2)
at spr㞎.銤(String A_0, spr㑵 A_1)
at Spire.Presentation.Presentation.SaveToFile(String file, FileFormat fileFormat)
at Program.<Main>$(String[] args)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
--- End of inner exception stack trace ---
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Fri Sep 05, 2025 2:10 am

您好,

由于您的 Docker 环境中缺少 "Microsoft YaHei Mono" 字体,导致使用该字体的文本显示异常。请您在 Docker 容器的 /usr/share/fonts/ 目录中拷入该字体文件。
在 Windows 系统中请进入 C:\Windows\Fonts 路径,请卸载甜蜜早安吻.ttf和Microsoft YaHei Mono.ttf字体并重新安装字体(安装时请务必选择"为所有用户安装"选项,如图),以确保 Spire.PDF 能正常调用字体。
为所有用户安装字体.png

字体正确安装后,PDF 中所有字体将恢复正常显示效果,如下图所示。
字体正确应用结果.png
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 331
Joined: Mon Apr 14, 2025 3:33 am

Fri Sep 05, 2025 3:00 am

感谢回复,

Microsoft YaHei Mono 字体是windows系统内置的, 怎样实现用所有用户安装,
docker下的 Microsoft YaHei Mono 该字体已经通过下面的命令添加了, 是拷贝到的目录错了?
不理解的是, 在Spire.doc和xls组件下,字体的设置和显示都是正常的
# 安装自定义字体
RUN mkdir -p /usr/share/fonts/truetype/custom
COPY FONT/* /usr/share/fonts/truetype/custom/
RUN fc-cache -f -v


关于二楼的问题, 首次执行失败, 提醒字体没找到, 之后再执行才能成功, 有办法解决吗?

另外, 测试aspose.pdf组件, 实现相同的功能,设置相同的字体在win和docker下都能正常显示

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Fri Sep 05, 2025 3:21 am

感觉咱们的某些组件, 在字体的设置和打印方面可能存在一些问题, 以前有遇到过, 要重装字体才能生效, 又需要管理员权限,这在某些情况下不太现实, 而有的字体没选择为所有用户安装也能用, 用过同类的竞品组件, 确实没这个问题, 建议能审核并优化改进一下

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Fri Sep 05, 2025 5:12 am

经过测试,
windows下的字体问题解决了, 就是按"为所有用户安装"解决的
但是docker下的问题将/usr/share/fonts/truetype/custom改为/usr/share/fonts 后执行代码, 问题仍然存在

下面是docker下.csproj文件内容
Code: Select all
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Spire.Officefor.NETStandard" Version="10.7.0" />
    <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.116.0" />
  </ItemGroup>
</Project>


xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Fri Sep 05, 2025 11:50 am

您好,

关于您提到的首次运行报错而第二次运行正常的问题,我们在 Docker 环境下未能复现此情况。为了更好地排查问题,能否请您提供更多信息,例如您的 Docker 配置或 Dockerfile 内容?另外,请问您的代码是否在多线程环境下运行?在多线程场景中,资源加载时序可能影响字体调用,进而引发相关问题。

根据您提供的信息来看,您在 Docker 中仍出现字体问题的原因可能是程序缺少对相应字体的读取权限。建议您通过代码方式解决此问题,请在程序中添加以下代码段,其中 fonts为包含程序所需字体文件的目录路径:
String fontpath = @"fonts/";
Spire.Pdf.PdfDocument.LoadCustomFontFolder(fontpath);
最后,感谢您提出的宝贵建议,我们将持续优化产品功能并提高用户使用体验。
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 331
Joined: Mon Apr 14, 2025 3:33 am

Sat Sep 06, 2025 12:32 am

talia.liu wrote:您好,

关于您提到的首次运行报错而第二次运行正常的问题,我们在 Docker 环境下未能复现此情况。为了更好地排查问题,能否请您提供更多信息,例如您的 Docker 配置或 Dockerfile 内容?另外,请问您的代码是否在多线程环境下运行?在多线程场景中,资源加载时序可能影响字体调用,进而引发相关问题。

根据您提供的信息来看,您在 Docker 中仍出现字体问题的原因可能是程序缺少对相应字体的读取权限。建议您通过代码方式解决此问题,请在程序中添加以下代码段,其中 fonts为包含程序所需字体文件的目录路径:
String fontpath = @"fonts/";
Spire.Pdf.PdfDocument.LoadCustomFontFolder(fontpath);
最后,感谢您提出的宝贵建议,我们将持续优化产品功能并提高用户使用体验。


感谢回复!
经过大量测试, 使用LoadCustomFontFolder函数加载字体, 代码执行中不再报异常, 但在win和docker下有与前面反馈的相同的问题: 有些字体能加载,有些字体不能加载(如果是您提到的权限问题,无法理解为什么有字体就能加载? 它们都是同时拷进去的自定义字体,在同一目录),
具体不同点:
1.在docker下不用LoadCustomFontFolder函数,代码第一次执行时, 会报没找到字体的异常(二楼贴子中有), 第二次执行时不报异常,但是用(Noto Sans CJK JP)字体替换了无法识别的字体(Microsoft YaHei Mono)
2.在docker下使用LoadCustomFontFolder函数,不再报字体未找到的异常,能正常生成pdf文档, 但是本该是Microsoft YaHei Mono字体的文本却设置成了"甜蜜早安吻"字体(自定义加载的字体文件夹下只有Microsoft YaHei Mono和甜蜜早安吻这两个字体)
3.在win10下用linqpad测试,每次执行都没有报错, 但是结果和docker下是完全相同的, 也和不使用LoadCustomFontFolder函数加载字体的结果完全相同,另外在win10下Microsoft YaHei Mono字体是win10系统内置的, 但结果始终用的是Microsoft YaHei字体(3楼您贴子生成的文档中字体名也是Microsoft YaHei,也是错的, 和我的结果一样), 而Doc和Xls组件设置该字体后显示的字体名却是正确的.
PS: Microsoft YaHei和Microsoft YaHei Mono是不同的字体, 前者的文件是三个.ttc文件,后者是单个.ttf文件

综上所述:
A)以前反馈过的所有问题都是因为某些字体未识别造成的,而非权限或多线程等原因导致!
B)Spire.Presentation下的SetCustomFontsDirctory和Spire.Pdf下的LoadCustomFontFolder函数在docker中确实抑制了异常的发生,无法识别的字体会用其中的某个字体替代

另外, 有没有类似LoadCustomFontFolder的全局设置字体文件夹的函数? 在代码开头设置一次,所有的组件都不用再设置了,例如: Spire.SetGlobalCustomFontsFolders("/fonts"); 这样就不用打包字体到docker镜像中了, 我在Barcode组件下没有找到类似的函数.

这些字体问题貌似只存在于Spire.Pdf, Spire.Presentation, Spire.Barcode组件中, 而spire.Doc和Spire.Xls则不存在这些问题, 字体都可以正确设置(但是如果另存为pdf文件仍然有问题,下面贴子有提到),

下面是问题复现的操作演示视频和相关的(linqpad代码,用到的字体)下载链接,期待再次核实并改进, 谢谢!
https://download.ru/files/7p3hGEpX

下面是同类竞品aspose.pdf对于演示中的3种字体的加载代码, win(字体是/否为所有用户安装)和docker下均测试成功
Code: Select all
using System;
using System.IO;
using Aspose.Pdf;
using Aspose.Pdf.Text;
using Aspose.Pdf.Facades;

// 创建文档
Document pdfDocument = new Document();
pdfDocument.Pages.Add();
Page pdfPage = pdfDocument.Pages[1];

// 三种字体文件路径
string font1 = @"D:\Aspose.Pdf\FONT\甜蜜早安吻.ttf";
string font2 = @"D:\Aspose.Pdf\FONT\白桃糖果奶酪体.ttf";
string font3 = @"D:\Aspose.Pdf\FONT\Microsoft-YaHei-Mono.ttf";

// 基础坐标
double x = 100;
double y = 600;
double offset = 40; // 每行上下错开的距离

// 添加第一个字体
TextFragment tf1 = new TextFragment("Hello China, 你好, 中国!");
tf1.Position = new Position(x, y);
tf1.TextState.FontSize = 14;
tf1.TextState.Font = FontRepository.OpenFont(font1);
tf1.TextState.BackgroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.LightGray);
tf1.TextState.ForegroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.Red);

// 第二个字体
TextFragment tf2 = new TextFragment("Hello China, 你好, 中国!");
tf2.Position = new Position(x, y - offset);
tf2.TextState.FontSize = 14;
tf2.TextState.Font = FontRepository.OpenFont(font2);
tf2.TextState.BackgroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.LightGray);
tf2.TextState.ForegroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.Blue);

// 第三个字体
TextFragment tf3 = new TextFragment("Hello China, 你好, 中国!");
tf3.Position = new Position(x, y - offset * 2);
tf3.TextState.FontSize = 14;
tf3.TextState.Font = FontRepository.OpenFont(font3);
tf3.TextState.BackgroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.LightGray);
tf3.TextState.ForegroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.Green);

// 添加到页面
TextBuilder textBuilder = new TextBuilder(pdfPage);
textBuilder.AppendText(tf1);
textBuilder.AppendText(tf2);
textBuilder.AppendText(tf3);

// 保存
pdfDocument.Save("三种字体示例.pdf");
Last edited by xyzxyzxyz on Sun Sep 07, 2025 1:45 pm, edited 21 times in total.

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Sat Sep 06, 2025 2:18 am

在docker下执行下面的Barcode组件的代码, 和pdf组件还有不同, 要先执行两次(报字体未找到的异常), 在第三次执行时才能成功, 生成文件中字体也是对, 奇怪的是"甜蜜早安吻"这个字体在pdf组件中是能识别的,不报错的.

Barcode组件有类似pdf组件的LoadCustomFontFolder函数吗? 因为Spire.Presentation下的SetCustomFontsDirctory和Spire.Pdf下的LoadCustomFontFolder函数在docker中确实抑制了异常的发生,无法识别的字体会用其中的某个字体替代,

Code: Select all
using System;
using System.IO;
using System.Drawing;
using SkiaSharp;

// Spire.Barcode
var bs = new Spire.Barcode.BarcodeSettings();
bs.Type = Spire.Barcode.BarCodeType.Code39;
bs.Data = "*ABC 12345*";
bs.SetTextFont("甜蜜早安吻", 10f, Spire.Barcode.Publics.Drawing.FontStyle.Regular);
// bs.SetTextFont("Microsoft YaHei Mono", 10f, Spire.Barcode.Publics.Drawing.FontStyle.Bold);
var bg = new Spire.Barcode.BarCodeGenerator(bs);
var skimage = bg.GenerateImage();
var data = skimage.Encode(SKEncodedImageFormat.Png, 100);
var stream = File.OpenWrite("/output/Spire.Barcode.png");
data.SaveTo(stream);
stream.Dispose();
skimage.Dispose();
Console.WriteLine("Spire.Barcode create!");
Last edited by xyzxyzxyz on Sat Sep 06, 2025 4:07 am, edited 3 times in total.

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Sat Sep 06, 2025 3:25 am

下面的Spire.Doc代码在docker下执行, 不会报错, 使用或不使用SetGlobalCustomFontsFolders函数效果都一样, 生成的docx文件中的字体名(Microsoft YaHei Mono)显示正确, 但生成的pdf文件中的中文字体乱码, 字体名显示: DejaVuSerif

Code: Select all
using SkiaSharp;
using Spire.Doc;
using System;
using System.IO;

Spire.Doc.Document.SetGlobalCustomFontsFolders("/usr/share/fonts");

// Spire.Doc
var document = new Spire.Doc.Document();
var section = document.AddSection();
var paragraph = section.AddParagraph();
var textRange = paragraph.AppendText("Spire.Doc! 你好, 中国!");
textRange.CharacterFormat.FontName = "Microsoft YaHei Mono";
textRange.CharacterFormat.FontSize = 20;
document.SaveToFile("/output/Spire.Doc.docx", Spire.Doc.FileFormat.Docx);
Console.WriteLine("Spire.Doc.docx create!");

document.SaveToFile("/output/Spire.Doc.pdf", Spire.Doc.FileFormat.PDF);
Console.WriteLine("Spire.Doc.pdf create!");


xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Mon Sep 08, 2025 8:05 am

您好,

感谢您的详细分享!
很抱歉由于周末的原因未能及时回复。经过多次测试,我们得出的具体结果如下:
1.Spire.Doc :在 Windows 和 Docker 环境下,Spire.Doc 均能正确应用“Microsoft YaHei Mono”、“甜蜜早安吻”及“白桃糖果奶酪体”字体生成 DOCX 文档。但在将 DOCX 转换为 PDF 时,“Microsoft YaHei Mono”和“白桃糖果奶酪体”的文本内容出现了字体替换现象,未能输出正确表现得pdf文档。
2.Spire.PDF & Spire.Barcode :在 Windows 和 Docker 环境下,两者均仅能正确渲染“甜蜜早安吻”字体的文本。“Microsoft YaHei Mono”和“Aa白桃糖果奶酪体”字体未能被正确调用,出现了字体替换或显示乱码的情况。
3.Spire.Presentation :在 Windows 和 Docker 两种环境下,Spire.Presentation 均成功调用并正确应用了全部三种字体,生成了符合预期的演示文稿,结果如截图所示。
spire.presentation.png

以上结果基本复现了您所遇到的问题。针对这些问题,我们已分别将情况1记录至问题跟踪系统(编号:SPIREDOC-11527),情况2记录至问题跟踪系统(编号:SPIREPDF-7706)。同时,Spire.Barcode 目前暂不支持自定义字体文件夹的功能需求,我们也已将其记录在产品更新系统中,跟踪编号为 SPIREBARCODE-284。
我们的开发团队将对这些问题进行进一步调查,一旦有任何进展,我会第一时间通知您。
再次感谢您的合作与宝贵建议!
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 331
Joined: Mon Apr 14, 2025 3:33 am

Tue Sep 09, 2025 1:31 am

感谢回复!
如下功能建议望考虑一下:
1. 在win下很多时候字体不识别是因为没有"为所有用户安装字体", 但这个操作是需要管理员权限的, 如果没有权限就无法使用字体, 但字体实际已经安装到用户字体文件夹下, 此时用下面的代码就能解决, 那就把这代码在api内部默认执行一下
Code: Select all
string userFontDir = Path.Combine(
   Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
   "Microsoft", "Windows", "Fonts");
Spire.Pdf.PdfDocument.LoadCustomFontFolder(userFontDir);


2.在docker下, 经过前面一些测试, 发现执行Spire.Pdf.PdfDocument.LoadCustomFontFolder("/usr/share/fonts"); 函数后,问题就少很多, 本身就是root用户不存在权限问题, 还是系统默认的字体目录,为何非要显示加载一下呢? 最好能顺便能查清原因彻底解决

这些功能不加代码就能自动实现是最好的, 或者有个全局的设置函数 Spire.SetGlobalCustomFontsFolders("/fonts")

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Tue Sep 09, 2025 9:50 am

您好,

感谢您的反馈。
关于在Windows环境下"对所有用户安装"字体的问题,当为所有用户安装字体,字体是在系统级别字体目录,通常是"C:\Windows\Fonts",当仅为当前用户安装,字体通常是安装在用户专属字体目录,例如:“C:\Users\<用户名>\AppData\Local\Microsoft\Windows\Fonts”,你提供的方法在某些情况下是可以读取到此路径,但也有可能因为权限问题无法获取正确的用户名,从而获取不到正确的路径。因此目前我们程序只从系统默认路径"C:\Windows\Fonts"读取字体,如果需要指定从其它路径读取,就使用前面提及的指定路径方式。目前暂时不考虑添加自动获取用户专属字体目录这部分到产品内部。感谢理解。
关于您在Docker环境中默认路径字体路径的问题,在完整的linux 系统有/etc/fonts/fonts.conf 配置文件内部通过 <dir> 标签包含了 /usr/share/fonts 和 /usr/local/share/fonts 等标准路径。默认获取就会找到。但Docker镜像一般直接创建的是“不完整”的系统,默认是没有类似的配置文件。因此docker 环境下通常建议代码指定下路径。
针对你提到的全局设置,因为我们各产品是独立的,目前指定文件夹方法在每个产品下都独立调用,这样也是为了兼容所有客户(不管是用单产品还是用组合产品)的使用。
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 331
Joined: Mon Apr 14, 2025 3:33 am

Thu Sep 11, 2025 1:01 am

您好,
在各个组件代码中设置自定义字体文件夹的使用逻辑是怎样的?
设置好后, 代码中能用的字体就只限于自定义字体文件夹中的字体了吗?
还是说代码中所用的字体,如果在系统字体文件夹中没找到的情况下,再从自定义字体文件夹中寻找?

xyzxyzxyz
 
Posts: 64
Joined: Fri Dec 27, 2024 1:10 pm

Thu Sep 11, 2025 6:23 am

您好,

感谢您的询问。
在指定自定义字体路径的情况下,Spire组件对系统字体文件夹和自定义字体文件夹下的字体一起使用,并不只限于使用自定义字体文件夹下的字体。
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 331
Joined: Mon Apr 14, 2025 3:33 am

Return to 中文技术支持