我正在使用 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/