用于嵌入式字体的PDFsharp / MigraDoc字体解析器:System.ArgumentException: F
本文关键字:字体 System ArgumentException MigraDoc 嵌入式 PDFsharp 用于 | 更新日期: 2023-09-27 18:13:56
我使用MigraDoc在我的ASP中生成pdf。NET5 MVC6 Web应用程序,部署到Azure云。我使用的是1.50 beta-2版本,但我也尝试过使用v1.50 beta-1和v1.32。
当应用程序在本地运行时,我已经成功地生成了pdf。然而,当应用程序在云服务器上运行时,由于无法访问任何字体,我在生成pdf时遇到了很大的麻烦。遵循PDFsharp文档,我尝试通过在我的代码中嵌入字体来创建一个"私有字体"。
我成功地在云端直接使用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博客上的优秀指南(这是beta-2的新指南,尽管我之前也遵循了他早期的beta-1帖子)。他的项目对我来说非常适合,就目前而言。
我实现了在我的Web App项目中使用的示例。它的完全与托马斯的代码相同,除了main
是我的控制器中的一个方法,它在按钮点击上运行:
字体解析器类:
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;
}
}
}
家庭控制器:
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;
}
}
当我运行应用程序并单击触发演示代码的按钮时,我得到一个错误"字体'Ubuntu'找不到",发生在renderer.RenderDocument()中。我如何让字体解析器找到/识别字体,这样我就可以使用MigraDoc在我的ASP上生成pdf。. NET MVC应用程序?
完整的错误信息和堆栈跟踪如下:
'/'应用程序服务器错误。
字体无法找到Ubuntu。
描述:在执行过程中发生未处理的异常当前的web请求。请查看堆栈跟踪了解更多信息有关错误及其在代码中的起源的信息。
Exception Details: System。字体'Ubuntu'不能是发现。
源错误:
Line 305: Line 306: renderer.Document = document; Line 307: renderer.RenderDocument(); Line 308: Line 309: // Send PDF to browser
源文件:C:'Users'User'Documents'Visual Studio 2015'Projects'DocumentGenerator'DocumentGenerator'Controllers'HomeController.cs行:307
堆栈跟踪:
[ArgumentException: Font 'Ubuntu' cannot found.]
System.Drawing.FontFamily.CreateFontFamily(String name, FontCollection fontCollection) +1123173 System.Drawing.FontFamily..ctor(String name) +11 PdfSharp.Drawing.XFontFamily..ctor(String name) +92 MigraDoc.Rendering.FontHandler.GetDescent(XFont font) +129 MigraDoc.Rendering.ParagraphRenderer.CalcVerticalInfo(XFont font) +154 MigraDoc.Rendering.ParagraphRenderer.InitFormat(Area area, FormatInfo previousFormatInfo) +392 MigraDoc.Rendering.ParagraphRenderer.Format(Area area, FormatInfo previousFormatInfo) +62 MigraDoc.Rendering.TopDownFormatter.FormatOnAreas(XGraphics gfx, Boolean topLevel) +738 MigraDoc.Rendering.FormattedDocument.Format(XGraphics gfx) +647 MigraDoc.Rendering.DocumentRenderer.PrepareDocument() +269 MigraDoc.Rendering.PdfDocumentRenderer.PrepareDocumentRenderer(Boolean prepareCompletely) +119 MigraDoc.Rendering.PdfDocumentRenderer.PrepareRenderPages() +19 MigraDoc.Rendering.PdfDocumentRenderer.RenderDocument() +13 DocumentGenerator.Controllers.HomeController.WriteDocument(Document document, PdfDocumentRenderer renderer) in C:'Users'User'Documents'Visual Studio 2015'Projects'DocumentGenerator'DocumentGenerator'Controllers'HomeController.cs:307 DocumentGenerator.Controllers.HomeController.DemoProjectMain() in C:'Users'User'Documents'Visual Studio 2015'Projects'DocumentGenerator'DocumentGenerator'Controllers'HomeController.cs:165 DocumentGenerator.Controllers.HomeController.CreateDocument(CreateDocumentViewModel model, String command) in C:'Users'User'Documents'Visual Studio 015'Projects'DocumentGenerator'DocumentGenerator'Controllers'HomeController.cs:56 lambda_method(Closure , ControllerBase , Object[] ) +146 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +157 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27 System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22 System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32 System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50 System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225 System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34 System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26 System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100 System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9723757 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
版本信息:Microsoft .NET Framework Version:4.0.30319;ASP。净版:4.6.79.0
您正在使用GDI构建的MigraDoc。错误信息来自GDI+。
我的示例代码是用WPF构建测试的。请在您的服务器上试用WPF版本。我猜你仍然必须使用XPrivateFontCollection与GDI构建。如果你想在你的服务器上坚持GDI构建,删除IFontResolver并使用XPrivateFontCollection。