Iva*_*van 6 c# asp.net-mvc fonts pdfsharp migradoc
我正在使用 MigraDoc 在部署到 Azure 云的 ASP.NET5 MVC6 Web 应用程序中生成 PDF。我使用的是 1.50 beta-2 版本,但我也尝试过使用 v1.50 beta-1 和 v1.32。
\n\n当应用程序在本地运行时,我已成功生成 PDF。然而,当应用程序在云服务器上运行时,由于无法访问任何字体,我在生成 PDF 时遇到了很大的问题。 按照 PDFsharp 文档,我尝试通过在代码中嵌入字体来创建“私有字体”。
\n\n我直接使用 PDFsharp 在云上成功生成了 PDF
\n\n public static MyResolver FontResolver = new MyResolver();\n public void RenderPdf(CreateDocumentViewModel viewModel)\n {\n GlobalFontSettings.FontResolver = FontResolver;\n //...\n XFont font = new XFont("times-roman", 12, XFontStyle.Regular);\n //This font is then used in DrawString.\n }\nRun Code Online (Sandbox Code Playgroud)\n\n不过,我现在想利用 MigraDoc,这样我就不必自己完成所有排版工作。
\n\n我在这里遵循了 Thomas H\xc3\xb6vel\ 博客上的优秀指南(这是 beta-2 的新指南,尽管我之前也关注过他之前关于 beta-1 的帖子)。他的项目在本地非常适合我。
\n\n我实现了在我的 Web 应用程序项目中使用的示例。它与 Thomas 的代码完全相同,除了我main的控制器中的一个方法是在单击按钮时运行的:
字体解析器类:
\n\npublic class DemoFontResolver : IFontResolver\n{\n public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)\n {\n // Ignore case of font names.\n var name = familyName.ToLower();\n\n // Deal with the fonts we know.\n switch (name)\n {\n case "ubuntu":\n if (isBold)\n {\n if (isItalic)\n return new FontResolverInfo("Ubuntu#bi");\n return new FontResolverInfo("Ubuntu#b");\n }\n if (isItalic)\n return new FontResolverInfo("Ubuntu#i");\n return new FontResolverInfo("Ubuntu#");\n\n case "janitor":\n return new FontResolverInfo("Janitor#");\n }\n\n // We pass all other font requests to the default handler.\n // When running on a web server without sufficient permission, you can return a default font at this stage.\n return PlatformFontResolver.ResolveTypeface(familyName, isBold, isItalic);\n }\n\n /// <summary>\n /// Return the font data for the fonts.\n /// </summary>\n public byte[] GetFont(string faceName)\n {\n switch (faceName)\n {\n case "Janitor#":\n return DemoFontHelper.Janitor;\n\n case "Ubuntu#":\n return DemoFontHelper.Ubuntu;\n\n case "Ubuntu#b":\n return DemoFontHelper.UbuntuBold;\n\n case "Ubuntu#i":\n return DemoFontHelper.UbuntuItalic;\n\n case "Ubuntu#bi":\n return DemoFontHelper.UbuntuBoldItalic;\n }\n\n return GetFont(faceName);\n }\n}\n\n/// <summary>\n/// Helper class that reads font data from embedded resources.\n/// </summary>\npublic static class DemoFontHelper\n{\n public static byte[] Janitor\n {\n get { return LoadFontData("RealEstateDocumentGenerator.fonts.janitor.Janitor.ttf"); }\n }\n\n // Tip: I used JetBrains dotPeek to find the names of the resources (just look how dots in folder names are encoded).\n // Make sure the fonts have compile type "Embedded Resource". Names are case-sensitive.\n public static byte[] Ubuntu\n {\n get { return LoadFontData("RealEstateDocumentGenerator.fonts.ubuntufontfamily0._80.Ubuntu-B.ttf"); }\n }\n\n public static byte[] UbuntuBold\n {\n get { return LoadFontData("RealEstateDocumentGenerator.fonts.ubuntufontfamily0._80.Ubuntu-B.ttf"); }\n }\n\n public static byte[] UbuntuItalic\n {\n get { return LoadFontData("RealEstateDocumentGenerator.fonts.ubuntufontfamily0._80.Ubuntu-RI.ttf"); }\n }\n\n public static byte[] UbuntuBoldItalic\n {\n get { return LoadFontData("RealEstateDocumentGenerator.fonts.ubuntufontfamily0._80.Ubuntu-BI.ttf"); }\n }\n\n /// <summary>\n /// Returns the specified font from an embedded resource.\n /// </summary>\n static byte[] LoadFontData(string name)\n {\n var assembly = Assembly.GetExecutingAssembly();\n\n using (Stream stream = assembly.GetManifestResourceStream(name))\n {\n if (stream == null)\n throw new ArgumentException("No resource with name " + name);\n\n int count = (int)stream.Length;\n byte[] data = new byte[count];\n stream.Read(data, 0, count);\n return data;\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n家庭控制器:
\n\npublic class HomeController : Controller\n{\n [HttpPost]\n public ActionResult CreateDocument()\n {\n DemoProjectMain();\n return View();\n }\n\n public void DemoProjectMain()\n {\n // That\'s all it takes to register your own fontresolver\n GlobalFontSettings.FontResolver = new DemoFontResolver();\n\n // And now the slightly modified MigraDoc Hello World sample.\n\n // Create a MigraDoc document\n Document document = DemoCreateDocument();\n document.UseCmykColor = true;\n\n // Create a renderer for the MigraDoc document.\n PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(unicode);\n\n WriteDocument(document, pdfRenderer);\n }\n\n public void WriteDocument(Document document, PdfDocumentRenderer renderer)\n {\n\n renderer.Document = document;\n renderer.RenderDocument();\n\n // Send PDF to browser\n MemoryStream stream = new MemoryStream();\n renderer.PdfDocument.Save(stream, false);\n Response.Clear();\n Response.ContentType = "application/pdf";\n Response.AddHeader("content-length", stream.Length.ToString());\n Response.BinaryWrite(stream.ToArray());\n Response.Flush();\n stream.Close();\n Response.End();\n }\n\n /// <summary>\n /// Creates an absolutely minimalistic document.\n /// </summary>\n static Document DemoCreateDocument()\n {\n // Create a new MigraDoc document\n Document document = new Document();\n\n DemoSetupStyles(document);\n\n // Add a section to the document\n Section section = document.AddSection();\n\n // Add a paragraph to the section\n Paragraph paragraph = section.AddParagraph();\n\n paragraph.Format.Font.Color = Color.FromCmyk(100, 30, 20, 50);\n\n // Add some text to the paragraph\n paragraph.AddFormattedText("Hello, World!", TextFormat.Bold);\n\n section.AddParagraph("Hello, World!");\n\n // Demonstration for Heading styles.\n paragraph = section.AddParagraph("Hello, World! (Heading 1)");\n paragraph.Style = StyleNames.Heading1;\n\n paragraph = section.AddParagraph("Hello, World! (Heading 2)");\n paragraph.Style = StyleNames.Heading2;\n\n paragraph = section.AddParagraph("Hello, World! (Heading 3)");\n paragraph.Style = StyleNames.Heading3;\n\n paragraph = section.AddParagraph("Hello, World! (Heading 4)");\n paragraph.Style = StyleNames.Heading4;\n\n paragraph = section.AddParagraph();\n\n paragraph.Format.Font.Color = Color.FromCmyk(100, 30, 20, 50);\n\n // Add some text to the paragraph\n paragraph.AddFormattedText("Hello, World!", TextFormat.Bold);\n\n section.AddParagraph("Hello, World!");\n\n return document;\n }\n\n private static void DemoSetupStyles(Document document)\n {\n // Default font for all styles.\n var style = document.Styles[StyleNames.Normal];\n style.Font.Name = "Ubuntu";\n\n // Overwrite font for headings 1 & 2.\n style = document.Styles[StyleNames.Heading1];\n style.Font.Name = "Janitor";\n style.Font.Size = 32;\n\n // Heading 2 inherits font from Heading 1.\n style = document.Styles[StyleNames.Heading2];\n style.Font.Size = 28;\n\n // Set normal font for Heading 3.\n style = document.Styles[StyleNames.Heading3];\n style.Font.Name = "Ubuntu";\n style.Font.Size = 24;\n\n style = document.Styles[StyleNames.Heading4];\n style.Font.Size = 20;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n当我运行应用程序并单击触发演示代码的按钮时,我在 renderer.RenderDocument() 处收到错误“无法找到 Font \'Ubuntu\'”。 如何让字体解析器查找/识别字体,以便我可以使用 MigraDoc 在 ASP.NET MVC 应用程序上生成 PDF?
\n\n完整的错误消息和堆栈跟踪如下:
\n\n\n\n\'/\' 应用程序中的服务器错误。
\n\n找不到字体“Ubuntu”。
\n\n描述: 执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其在代码中的来源的详细信息。\n
\n\n异常详细信息:System.ArgumentException:找不到字体“Ubuntu”。
\n\n来源错误:
\n\nRun Code Online (Sandbox Code Playgroud)\n\nLine 305:\nLine 306: renderer.Document = document;\nLine 307: renderer.RenderDocument();\nLine 308:\nLine 309: // Send PDF to browser\n源文件:C:\\ Users \\ User \\ Documents \\ Visual Studio 2015 \\ Projects \\ DocumentGenerator \\ DocumentGenerator \\ Controllers \\ HomeController.cs \\ n行:307
\n\n堆栈跟踪:
\n\n[ArgumentException:找不到字体“Ubuntu”。]
\n\nRun Code Online (Sandbox Code Playgroud)\n\nSystem.Drawing.FontFamily.CreateFontFamily(String name, FontCollection fontCollection) +1123173\nSystem.Drawing.FontFamily..ctor(String name) +11\nPdfSharp.Drawing.XFontFamily..ctor(String name) +92\nMigraDoc.Rendering.FontHandler.GetDescent(XFont font) +129\nMigraDoc.Rendering.ParagraphRenderer.CalcVerticalInfo(XFont font) +154\nMigraDoc.Rendering.ParagraphRenderer.InitFormat(Area area, FormatInfo previousFormatInfo) +392\nMigraDoc.Rendering.ParagraphRenderer.Format(Area area, FormatInfo previousFormatInfo) +62\nMigraDoc.Rendering.TopDownFormatter.FormatOnAreas(XGraphics gfx, Boolean topLevel) +738\nMigraDoc.Rendering.FormattedDocument.Format(XGraphics gfx) +647\nMigraDoc.Rendering.DocumentRenderer.PrepareDocument() +269\nMigraDoc.Rendering.PdfDocumentRenderer.PrepareDocumentRenderer(Boolean prepareCompletely) +119\nMigraDoc.Rendering.PdfDocumentRenderer.PrepareRenderPages() +19\nMigraDoc.Rendering.PdfDocumentRenderer.RenderDocument() +13\nDocumentGenerator.Controllers.HomeController.WriteDocument(Document document, PdfDocumentRenderer renderer) in C:\\Users\\User\\Documents\\Visual Studio 2015\\Projects\\DocumentGenerator\\DocumentGenerator\\Controllers\\HomeController.cs:307\nDocumentGenerator.Controllers.HomeController.DemoProjectMain() in C:\\Users\\User\\Documents\\Visual Studio 2015\\Projects\\DocumentGenerator\\DocumentGenerator\\Controllers\\HomeController.cs:165\nDocumentGenerator.Controllers.HomeController.CreateDocument(CreateDocumentViewModel model, String command) in C:\\Users\\User\\Documents\\Visual Studio 015\\Projects\\DocumentGenerator\\DocumentGenerator\\Controllers\\HomeController.cs:56\nlambda_method(Closure , ControllerBase , Object[] ) +146\nSystem.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14\nSystem.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +157\nSystem.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27\nSystem.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22\nSystem.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29\nSystem.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49\nSystem.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32\nSystem.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50\nSystem.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225\nSystem.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10\nSystem.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10\nSystem.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49\nSystem.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34\nSystem.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26\nSystem.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100\nSystem.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10\nSystem.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49\nSystem.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27\nSystem.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13\nSystem.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29\nSystem.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49\nSystem.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36\nSystem.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12\nSystem.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22\nSystem.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49\nSystem.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26\nSystem.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10\nSystem.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21\nSystem.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29\nSystem.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49\nSystem.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 \nSystem.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9\nSystem.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9723757\nSystem.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155\n版本信息: Microsoft .NET Framework 版本:4.0.30319;\n ASP.NET 版本:4.6.79.0
\n
您正在使用 MigraDoc 的 GDI 版本。错误消息来自 GDI+。
我的示例代码已使用 WPF 构建进行了测试。请尝试在您的服务器上构建 WPF。
AFAIK 您仍然需要在 GDI 构建中使用 XPrivateFontCollection。如果您想坚持在服务器上构建 GDI,请删除 IFontResolver 并使用 XPrivateFontCollection。
| 归档时间: |
|
| 查看次数: |
7278 次 |
| 最近记录: |