【问题标题】:How to use Fonts in PDFsharp in my Website?如何在我的网站中使用 PDFsharp 中的字体?
【发布时间】:2016-05-23 15:59:08
【问题描述】:

我只是在 Azure WebApplication 网站上使用 Arial 字体,但是当我到达这一行时:

MainFont = new XFont("Arial", FontSize);

它抛出异常读取:Font data could not retrieved.

我原以为 Arial 会安装在服务器上...我还尝试将其更改为 Sans-Serif 以匹配 Microsoft 生成的网站的默认字体...但它仍然失败。

我也尝试将 Arial.ttf 添加到项目中,但没有奏效。

【问题讨论】:

    标签: c# asp.net pdfsharp


    【解决方案1】:

    感谢@PDFSharp 团队的指点。这是我对 PdfSharp 1.5 beta3b 的实现:

    将您想要的字体添加到您的项目中 - 在下面的示例中,我将 Arial 放入 MyProject\fonts\arial\arial.ttf 等。将每个字体文件设置为嵌入式资源(属性 -> 构建操作)。

    使用这样的静态调用只应用一次字体解析器:

    MyFontResolver.Apply(); // Ensures it's only applied once
    

    这是字体解析器类:

    class MyFontResolver : IFontResolver
    {
        public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
        {
            // Ignore case of font names.
            var name = familyName.ToLower().TrimEnd('#');
    
            // Deal with the fonts we know.
            switch (name)
            {
                case "arial":
                    if (isBold)
                    {
                        if (isItalic)
                            return new FontResolverInfo("Arial#bi");
                        return new FontResolverInfo("Arial#b");
                    }
                    if (isItalic)
                        return new FontResolverInfo("Arial#i");
                    return new FontResolverInfo("Arial#");
            }
    
            // We pass all other font requests to the default handler.
            // When running on a web server without sufficient permission, you can return a default font at this stage.
            return PlatformFontResolver.ResolveTypeface(familyName, isBold, isItalic);
        }
    
        /// <summary>
        /// Return the font data for the fonts.
        /// </summary>
        public byte[] GetFont(string faceName)
        {
            switch (faceName)
            {
                case "Arial#":
                    return FontHelper.Arial;
    
                case "Arial#b":
                    return FontHelper.ArialBold;
    
                case "Arial#i":
                    return FontHelper.ArialItalic;
    
                case "Arial#bi":
                    return FontHelper.ArialBoldItalic;
            }
    
            return null;
        }
    
    
        internal static MyFontResolver OurGlobalFontResolver = null;
    
        /// <summary>
        /// Ensure the font resolver is only applied once (or an exception is thrown)
        /// </summary>
        internal static void Apply()
        {
            if (OurGlobalFontResolver == null || GlobalFontSettings.FontResolver == null)
            {
                if (OurGlobalFontResolver == null)
                    OurGlobalFontResolver = new MyFontResolver();
    
                GlobalFontSettings.FontResolver = OurGlobalFontResolver;
            }
        }
    }
    
    
    /// <summary>
    /// Helper class that reads font data from embedded resources.
    /// </summary>
    public static class FontHelper
    {
        public static byte[] Arial
        {
            get { return LoadFontData("MyProject.fonts.arial.arial.ttf"); }
        }
    
        public static byte[] ArialBold
        {
            get { return LoadFontData("MyProject.fonts.arial.arialbd.ttf"); }
        }
    
        public static byte[] ArialItalic
        {
            get { return LoadFontData("MyProject.fonts.arial.ariali.ttf"); }
        }
    
        public static byte[] ArialBoldItalic
        {
            get { return LoadFontData("MyProject.fonts.arial.arialbi.ttf"); }
        }
    
        /// <summary>
        /// Returns the specified font from an embedded resource.
        /// </summary>
        static byte[] LoadFontData(string name)
        {
            var assembly = Assembly.GetExecutingAssembly();
    
            // Test code to find the names of embedded fonts
            //var ourResources = assembly.GetManifestResourceNames();
    
            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;
            }
        }
    }
    

    这是一个基于这两个几乎相同的帖子的单一、完整和工人阶级:this blogthis forum

    【讨论】:

    • 我有这个错误:'没有名为 Psidar.WebAPI.Content.Fonts.arial.arial.ttf 的资源'
    【解决方案2】:

    使用最新版本的 PDFsharp(当前为 1.50 beta 3)并实施 IFontResolver。

    另请参阅:
    https://stackoverflow.com/a/32489271/162529
    https://stackoverflow.com/a/29059207/162529

    该字体可能已安装在服务器上,但 PDFsharp 无法读取它。

    【讨论】:

    • 查看这些链接中的代码,看起来我仍然需要将字体文件附加到我的项目中,即使它可能存在于服务器上 - 对吗?
    • PDFsharp 必须能够访问字体文件。如果它位于服务器上受保护的系统文件夹中,那么它仍然是遥不可及的。使用 PDFsharp 1.50,您需要一个字节数组,因此您可以将其作为资源添加到您的程序集或作为内容文件添加到您的项目中。
    猜你喜欢
    • 2015-05-13
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 2011-05-24
    • 2015-09-26
    • 2011-02-22
    • 2012-10-23
    • 2011-02-21
    相关资源
    最近更新 更多