豪情万千的米饭 · 如何为对象(minIO)设置生命周期规则?- ...· 1 年前 · |
爽快的大蒜 · [Ansible专栏]Ansible安装和基 ...· 1 年前 · |
乖乖的小熊猫 · swagger入参注解分组-掘金· 1 年前 · |
无邪的橡皮擦 · 如何在SymPy中查找表达式中是否包含复数i ...· 1 年前 · |
我正在用iTextSharp (5.5.7.0)在ASP.NET MVC5应用程序中创建一些PDF文档,但是我无法更改字体。我已经尝试了几乎所有我能够找到这样或从其他资源。
PDF生成代码如下:
public Byte[] GetRecordsPdf(RecordsViewModel model)
var viewPath = "~/Template/RecordTemplate.cshtml";
var renderedReport = RenderViewToString(viewPath, model);
FontFactory.RegisterDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Fonts));
using (var ms = new MemoryStream())
using (var doc = new Document())
doc.SetPageSize(PageSize.A4.Rotate());
using (var writer = PdfWriter.GetInstance(doc, ms))
doc.Open();
using (var html = new MemoryStream(Encoding.Default.GetBytes(renderedReport)))
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, html, Encoding.Default);
doc.Close();
var bytes = ms.ToArray();
return bytes;
}
实际的renderedReport包含在HTML变量中(我有强类型的.cshtml文件,我使用MVC呈现它,然后以字符串形式返回.cshtml)。
我试过注册一些特定的字体,但没有帮助。我还尝试在我的机器上注册所有字体(如上面的例子所示),但这也没有帮助。字体已经加载,我已经在调试模式下检查过了。
CSS嵌入HTML文件(在标题、样式标记中),如下所示:
body {
font-size: 7px;
font-family: Comic Sans MS;
}
(为了测试,我决定使用Comic,因为我可以很容易地识别它,实际上我对Arial更感兴趣)。
和我实际上能够用CSS的字体家族属性更改字体,但只能从默认情况下由iTextSharp预加载的字体- Times、Arial、Courier和其他一些字体(我认为是Helvetica)。当我将字体更改为- Comic时,或者其他一些没有预加载的iTextSharp呈现为默认字体时, (我会说)。
我需要更改字体的原因是我在呈现的HTML (ČĆŠĐŽčćšđž)中有一些克罗地亚字符,这些字符在PDF中缺失,目前我认为主要原因是字体。
我遗漏了什么?
发布于 2015-12-22 15:02:25
有几件事能让这件事成功。
首先,
XMLWorkerHelper
在默认情况下不使用
FontFactory
,您需要使用
ParseXHtml()
的重载之一,它需要一个
IFontProvider
。这两个重载都要求为
Stream
文件指定一个
null
,但如果CSS驻留在HTML中,则只需传递
null
即可。幸运的是,
FontFactory
有一个静态属性来实现这个功能,您可以使用这个属性称为
FontFactory.FontImp
。
// **This guy**
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHTML, null, Encoding.UTF8, FontFactory.FontImp);
第二,我知道你说你试图注册你的整个字体目录出于绝望,但这可能是一个相当昂贵的调用。如果可以,请始终尝试注册所需的字体。虽然是可选的,但我也强烈建议您显式地定义字体的别名,因为字体可以有几个名称,而且它们并不总是我们所想的那样。
FontFactory.Register(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "comic.ttf"), "Comic Sans MS");
第三,这可能不会影响到您,但是HTML中没有出现的任何标记,即使它们在逻辑上是隐含的,也不会从CSS中应用到它们的样式。这听起来很奇怪,所以换句话来说,如果你的HTML只是
<p>Hello</p>
,而你的
body{font-size: 7px;}
是
body{font-size: 7px;}
,字体大小就不会被应用,因为你的
<body>
缺少了
<body>
标签。
第四,这是可选的,但通常更容易分别指定HTML和CSS,我将在下面的示例中这样做。
您的代码是95%,所以只要做几个调整就可以了。我只是解析原始的HTML和CSS,而不是视图,但是您可以根据需要进行修改。请记住(我认为您知道这一点),iTextSharp不能只处理ASP.Net,所以您需要确保您的ASP.Net到HTML转换过程是正常的。
//Sample HTML and CSS
var html = @"<body><p>Sva ljudska bića rađaju se slobodna i jednaka u dostojanstvu i pravima. Ona su obdarena razumom i sviješću i trebaju jedna prema drugima postupati u duhu bratstva.</p></body>";
var css = "body{font-size: 7px; font-family: Comic Sans MS;}";
//Register a single font
FontFactory.Register(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "comic.ttf"), "Comic Sans MS");
//Placeholder variable for later
Byte[] bytes;
using (var ms = new MemoryStream()) {
using (var doc = new Document()) {
doc.SetPageSize(PageSize.A4.Rotate());
using (var writer = PdfWriter.GetInstance(doc, ms)) {
doc.Open();
//Get a stream of our HTML
using (var msHTML = new MemoryStream(Encoding.UTF8.GetBytes(html))) {
//Get a stream of our CSS
using (var msCSS = new MemoryStream(Encoding.UTF8.GetBytes(css))) {
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHTML, msCSS, Encoding.UTF8, FontFactory.FontImp);
乖乖的小熊猫 · swagger入参注解分组-掘金 1 年前 |