我正在使用 MigraDoc 在我的 ASP.NET5 MVC6 Web 应用程序中生成 PDF,该应用程序部署到 Azure 云。我使用的是 1.50 beta-2 版本,但我也尝试过使用 v1.50 beta-1 和 v1.32。

当应用程序在本地运行时,我已成功生成 PDF。但是,由于无法访问任何字体,当应用程序在云服务器上运行时,我在生成 PDF 时遇到了很大的麻烦。 Following the PDFsharp docs ,我尝试通过在我的代码中嵌入字体来创建“私有(private)字体”。

我直接使用 PDFsharp 在云上成功生成了 PDF

    public static MyResolver FontResolver = new MyResolver();
    public void RenderPdf(CreateDocumentViewModel viewModel)
    {
        GlobalFontSettings.FontResolver = FontResolver;
        //...
        XFont font = new XFont("times-roman", 12, XFontStyle.Regular);
        //This font is then used in DrawString.
    }

但是,我现在想利用 MigraDoc,这样我就不必自己进行所有排版。

我关注了 Thomas Hövel 博客 here (this is the new one for beta-2 上的优秀指南,尽管我之前也关注过 his earlier post for beta-1 )。他的项目在本地非常适合我。

我实现了在我的 Web App 项目中使用的示例。 与 Thomas 的代码完全相同,除了 main 是我的 Controller 中的一个方法,在单击按钮时运行:

字体解析器类:
public class DemoFontResolver : IFontResolver
{
    public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
    {
        // Ignore case of font names.
        var name = familyName.ToLower();

        // Deal with the fonts we know.
        switch (name)
        {
            case "ubuntu":
                if (isBold)
                {
                    if (isItalic)
                        return new FontResolverInfo("Ubuntu#bi");
                    return new FontResolverInfo("Ubuntu#b");
                }
                if (isItalic)
                    return new FontResolverInfo("Ubuntu#i");
                return new FontResolverInfo("Ubuntu#");

            case "janitor":
                return new FontResolverInfo("Janitor#");
        }

        // 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 "Janitor#":
                return DemoFontHelper.Janitor;

            case "Ubuntu#":
                return DemoFontHelper.Ubuntu;

            case "Ubuntu#b":
                return DemoFontHelper.UbuntuBold;

            case "Ubuntu#i":
                return DemoFontHelper.UbuntuItalic;

            case "Ubuntu#bi":
                return DemoFontHelper.UbuntuBoldItalic;
        }

        return GetFont(faceName);
    }
}

/// <summary>
/// Helper class that reads font data from embedded resources.
/// </summary>
public static class DemoFontHelper
{
    public static byte[] Janitor
    {
        get { return LoadFontData("RealEstateDocumentGenerator.fonts.janitor.Janitor.ttf"); }
    }

    // Tip: I used JetBrains dotPeek to find the names of the resources (just look how dots in folder names are encoded).
    // Make sure the fonts have compile type "Embedded Resource". Names are case-sensitive.
    public static byte[] Ubuntu
    {
        get { return LoadFontData("RealEstateDocumentGenerator.fonts.ubuntufontfamily0._80.Ubuntu-B.ttf"); }
    }

    public static byte[] UbuntuBold
    {
        get { return LoadFontData("RealEstateDocumentGenerator.fonts.ubuntufontfamily0._80.Ubuntu-B.ttf"); }
    }

    public static byte[] UbuntuItalic
    {
        get { return LoadFontData("RealEstateDocumentGenerator.fonts.ubuntufontfamily0._80.Ubuntu-RI.ttf"); }
    }

    public static byte[] UbuntuBoldItalic
    {
        get { return LoadFontData("RealEstateDocumentGenerator.fonts.ubuntufontfamily0._80.Ubuntu-BI.ttf"); }
    }

    /// <summary>
    /// Returns the specified font from an embedded resource.
    /// </summary>
    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;
        }
    }
}

家庭 Controller :
public class HomeController : Controller
{
    [HttpPost]
    public ActionResult CreateDocument()
    {
        DemoProjectMain();
        return View();
    }

    public void DemoProjectMain()
    {
        // That's all it takes to register your own fontresolver
        GlobalFontSettings.FontResolver = new DemoFontResolver();

        // And now the slightly modified MigraDoc Hello World sample.

        // Create a MigraDoc document
        Document document = DemoCreateDocument();
        document.UseCmykColor = true;

        // Create a renderer for the MigraDoc document.
        PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(unicode);

        WriteDocument(document, pdfRenderer);
    }

    public void WriteDocument(Document document, PdfDocumentRenderer renderer)
    {

        renderer.Document = document;
        renderer.RenderDocument();

        // Send PDF to browser
        MemoryStream stream = new MemoryStream();
        renderer.PdfDocument.Save(stream, false);
        Response.Clear();
        Response.ContentType = "application/pdf";
        Response.AddHeader("content-length", stream.Length.ToString());
        Response.BinaryWrite(stream.ToArray());
        Response.Flush();
        stream.Close();
        Response.End();
    }

    /// <summary>
    /// Creates an absolutely minimalistic document.
    /// </summary>
    static Document DemoCreateDocument()
    {
        // Create a new MigraDoc document
        Document document = new Document();

        DemoSetupStyles(document);

        // Add a section to the document
        Section section = document.AddSection();

        // Add a paragraph to the section
        Paragraph paragraph = section.AddParagraph();

        paragraph.Format.Font.Color = Color.FromCmyk(100, 30, 20, 50);

        // Add some text to the paragraph
        paragraph.AddFormattedText("Hello, World!", TextFormat.Bold);

        section.AddParagraph("Hello, World!");

        // Demonstration for Heading styles.
        paragraph = section.AddParagraph("Hello, World! (Heading 1)");
        paragraph.Style = StyleNames.Heading1;

        paragraph = section.AddParagraph("Hello, World! (Heading 2)");
        paragraph.Style = StyleNames.Heading2;

        paragraph = section.AddParagraph("Hello, World! (Heading 3)");
        paragraph.Style = StyleNames.Heading3;

        paragraph = section.AddParagraph("Hello, World! (Heading 4)");
        paragraph.Style = StyleNames.Heading4;

        paragraph = section.AddParagraph();

        paragraph.Format.Font.Color = Color.FromCmyk(100, 30, 20, 50);

        // Add some text to the paragraph
        paragraph.AddFormattedText("Hello, World!", TextFormat.Bold);

        section.AddParagraph("Hello, World!");

        return document;
    }

    private static void DemoSetupStyles(Document document)
    {
        // Default font for all styles.
        var style = document.Styles[StyleNames.Normal];
        style.Font.Name = "Ubuntu";

        // Overwrite font for headings 1 & 2.
        style = document.Styles[StyleNames.Heading1];
        style.Font.Name = "Janitor";
        style.Font.Size = 32;

        // Heading 2 inherits font from Heading 1.
        style = document.Styles[StyleNames.Heading2];
        style.Font.Size = 28;

        // Set normal font for Heading 3.
        style = document.Styles[StyleNames.Heading3];
        style.Font.Name = "Ubuntu";
        style.Font.Size = 24;

        style = document.Styles[StyleNames.Heading4];
        style.Font.Size = 20;
    }
}

当我运行应用程序并单击触发演示代码的按钮时,在 renderer.RenderDocument() 中出现错误“找不到字体‘Ubuntu’”。 如何让字体解析器找到/识别字体,以便我可以使用 MigraDoc 在我的 ASP.NET MVC 应用程序上生成 PDF?

完整的错误消息和堆栈跟踪如下:

最佳答案

您正在使用 MigraDoc 的 GDI 版本。错误消息来自 GDI+。

我的示例代码使用 WPF 构建进行了测试。请尝试在您的服务器上构建 WPF。

AFAIK 您仍然必须将 XPrivateFontCollection 与 GDI 版本一起使用。如果您想坚持在您的服务器上使用 GDI 构建,请删除 IFontResolver 并使用 XPrivateFontCollection。

关于c# - 嵌入字体的 PDFsharp/MigraDoc 字体解析器 : System. ArgumentException:找不到字体 'Ubuntu',我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32726223/

10-14 21:07
查看更多