Azure PDF Sharp 不使用 Unicode 字体

joe*_*hip 5 c# pdf unicode fonts azure

我们有一个使用 Azure 云服务托管的 C# 网站,并使用 PDF Sharp 生成 PDF 文档。

我们使用 Arial Unicode MS Regular 字体,因为我们有日语字体要显示。当网站在本地运行(从 Windows 7 上的 Visual Studio)时,字体会正确呈现。

我们使用 Azure 的启动脚本将字体安装到云服务服务器上,因为它默认没有安装。我已验证该字体已安装在云服务服务器 (Windows Server 2012) 上。

在 Azure 托管网站中,日语字体显示为正方形,即使 PDF 属性确实表明使用的字体是 Arial Unicode MS Regular。

为什么在云服务服务器上没有正确使用字体?

在 Azure 上运行的 Windows 2012 服务器生成的 PDF。 日文字体呈现为正方形,但属性表明使用的是 unicode 字体。

joe*_*hip 6

为了解决这个问题,我将问题交叉发布到 PDFSharp 论坛帖子,一个答案为我指明了创建要使用的字体解析器的正确方向:

  1. NuGet安装 PDFsharp 1.50 beta 2 的 WPF 版本
  2. 使用字体解析器选择字体在 PDFsharp 1.50 beta 2 或 MigraDoc 中使用私有字体
  3. 将 unicode 字体作为嵌入资源添加到项目中。

我将其部署到 Azure 云服务并确认正确使用了 unicode 字体。


PDFSharp 的文档是不完整的,因为它声明 GDI 构建是用于 .NET 网站的正确构建,而实际上在这种情况下并非如此。相反,使用 FontResolver 的 WPF 构建起作用了。


例子

安装程序FontResolverGlobal.asax.cs

PdfSharp.Fonts.GlobalFontSettings.FontResolver = new MyFontResolver();
Run Code Online (Sandbox Code Playgroud)

创建一个名为的新类MyFontResolver,它使用嵌入资源中包含的额外字体系列扩展默认实现。

字体本身应该通过 build action = 添加到字体目录中Embedded Resource

public class MyFontResolver : IFontResolver
{
    public FontResolverInfo ResolveTypeface(string familyName, 
                                            bool isBold, 
                                            bool isItalic)
    {
        // Ignore case of font names.
        var name = familyName.ToLower();

        // Add fonts here
        switch (name)
        {
            case "arial unicode ms":
                return new FontResolverInfo("ArialUnicodeMS#");
        }

        //Return a default font if the font couldn't be found
        //this is not a unicode font 
        return PlatformFontResolver.ResolveTypeface("Arial", isBold, isItalic);
    }

    // Return the font data for the fonts.
    public byte[] GetFont(string faceName)
    {
        switch (faceName)
        {
            case "ArialUnicodeMS#": return FontHelper.ArialUnicodeMS; break;
        }

        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

从嵌入资源中读取字体数据的助手类。

public static class FontHelper
{
    public static byte[] ArialUnicodeMS
    {
        //the font is in the folder "/fonts" in the project
        get { return LoadFontData("MyApp.fonts.ARIALUNI.TTF"); }
    }

    /// Returns the specified font from an embedded resource.
    static byte[] LoadFontData(string name)
    {

        var assembly = Assembly.GetExecutingAssembly();

        using (Stream stream = assembly.GetManifestResourceStream(name))
        {
            if (stream == null)
                throw new ArgumentException("No resource with name " + name);

            int count = (int)stream.Length;
            byte[] data = new byte[count];
            stream.Read(data, 0, count);
            return data;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

生成PDF时照常定义字体,例如:

 var style = document.Styles["Normal"];
 style.Font.Name = "Arial Unicode MS";
 style.Font.Size = 8;
Run Code Online (Sandbox Code Playgroud)