我正在使用MigraDoc在我的ASP.NET5 MVC6 Web应用程序中生成PDF,该应用程序部署在Azure云上。我使用的是版本1.50 beta-2,但我也尝试过使用v1.50 beta-1和v1.32。
当应用程序在本地运行时,我成功地生成了PDF。然而,由于无法访问任何字体,当应用程序在云服务器上运行时,我一直在努力生成PDF,遇到了很大的问题。按照PDFsharp文档的说明,我尝试通过将字体嵌入到我的代码中来创建“私有字体”。
我成功地使用PDFsharp直接在云上生成了PDF。
然而,我现在想利用MigraDoc,这样我就不必自己进行所有的排版工作了。
我按照Thomas Hövel博客上的优秀指南(这是beta-2的新指南)进行了操作,尽管我之前也曾经遵循他为beta-1所写的早期文章。他的项目对我来说完全正常,在本地运行良好。
我实现了示例以在我的Web App项目中使用。它与Thomas的代码完全相同,只是
当我运行应用程序并点击触发演示代码的按钮时,出现错误“无法找到字体'Ubuntu'”,该错误发生在renderer.RenderDocument()。如何使字体解析器能够找到/识别字体,以便我可以在我的ASP.NET MVC应用程序上使用MigraDoc生成PDF?完整的错误消息和堆栈跟踪如下:
当应用程序在本地运行时,我成功地生成了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项目中使用。它与Thomas的代码完全相同,只是
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()。如何使字体解析器能够找到/识别字体,以便我可以在我的ASP.NET MVC应用程序上使用MigraDoc生成PDF?完整的错误消息和堆栈跟踪如下:
Server Error in '/' Application.
Font 'Ubuntu' cannot be found.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: Font 'Ubuntu' cannot be found.
Source Error:
Line 305: Line 306: renderer.Document = document; Line 307: renderer.RenderDocument(); Line 308: Line 309: // Send PDF to browser
Source File: C:\Users\User\Documents\Visual Studio 2015\Projects\DocumentGenerator\DocumentGenerator\Controllers\HomeController.cs Line: 307
Stack Trace:
[ArgumentException: Font 'Ubuntu' cannot be 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
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.79.0
renderer.RenderDocument();
。您展示的HomeController源代码包含了这一行pdfRenderer.RenderDocument();
。也许您运行的代码不是您想要运行的代码 - 至少它不是您在这里展示的代码。这使得定位错误变得困难。 - I liked the old Stack Overflow