我正在尝试使用iTextSharp获取HTML内容并将其转换为PDF。一切都运行良好,除了字体真棒图标没有出现在结果PDF中。
我的.NET MVC应用程序是用C#编写的,它使用Font Awesome Free 5.0.12(使用Web Fonts with CSS方法),iTextSharp 5.5.13以及itextsharp.xmlworker和Vue.js框架。
当从浏览器中点击“打印”按钮时,会调用vue.js方法,该方法将转换HTML的内容(包含在隐藏的div中)并将其发布到适当的控制器方法(然后获取响应数据并加载它):
createPDF: function () {
commonEventBus.$emit("show-loading-overlay", "Loading");
var document = $("#printSummary");
var model = {
HtmlData: document.html()
}
return this.$http.post(commonApp.root + "PDF/Export", model, { responseType: "blob" })
.then(function (response) {
if (window.navigator && window.navigator.msSaveOrOpenBlob) { // for IE
window.navigator.msSaveOrOpenBlob(response.bodyBlob);
commonEventBus.$emit("hide-overlay");
}
else {
var fileURL = URL.createObjectURL(response.bodyBlob);
window.open(fileURL);
commonEventBus.$emit("hide-overlay");
}
});
},
PDFController中的Export方法如下:
[HttpPost]
[ValidateInput(false)]
public ActionResult Export(HtmlViewModel model)
{
var generator = new PDFGenerator();
return File(generator.Generate(model), "application/pdf", "Confirmation" + DateTime.Now + ".pdf");
}
PDFGenerator类中的Generate方法如下所示:
public byte[] Generate(HtmlViewModel html)
{
HtmlNode.ElementsFlags["br"] = HtmlElementFlag.Closed;
HtmlNode.ElementsFlags["input"] = HtmlElementFlag.Closed;
HtmlNode.ElementsFlags["hr"] = HtmlElementFlag.Closed;
HtmlNode.ElementsFlags["img"] = HtmlElementFlag.Closed;
HtmlDocument doc = new HtmlDocument();
doc.OptionFixNestedTags = true;
doc.LoadHtml(html.HtmlData);
html.HtmlData = doc.DocumentNode.OuterHtml;
byte[] bytesArray = null;
using (var ms = new MemoryStream())
{
using (var document = new Document(PageSize.A4, 40, 40, 40, 40))
{
using (PdfWriter writer = PdfWriter.GetInstance(document, ms))
{
document.Open();
using (var strReader = new StringReader(html.HtmlData))
{
//Set factories
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
//Set css
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
//Register a single font
cssResolver.AddCssFile(System.Web.HttpContext.Current.Server.MapPath("~/Content/bootstrap.css"), true);
cssResolver.AddCssFile(System.Web.HttpContext.Current.Server.MapPath("~/Content/app/print.css"), true);
//Export
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer)));
var worker = new XMLWorker(pipeline, true);
var xmlParse = new XMLParser(true, worker);
xmlParse.Parse(strReader);
xmlParse.Flush();
}
document.Close();
}
}
bytesArray = ms.ToArray();
}
return bytesArray;
}
知道如何让Font Awesome图标显示出来吗?例如,我在HTML代码中有类似的东西被转换,它在PDF中消失了:
<i class="fas fa-1x fa-shopping-cart"></i> Print Order
我也尝试使用unicode值,但没有运气:
<i class="fas"></i> Print Order
答案 0 :(得分:2)
iText对Font Awesome有零知识,所以你需要做更多的工作。以下是简单的测试/工作示例。
HTML:
<html>
<head>
<style>
.fas { font-family: FontAwesome; color:green; }
</style>
</head>
<body>
<i class='fas'></i> Print Order
</body></html>
解析代码 - 注意内联注释:
using (var stream = new FileStream(OUTPUT_FILE, FileMode.Create))
{
using (var document = new Document())
{
var writer = PdfWriter.GetInstance(document, stream);
document.Open();
var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
// path to fontawesome.css
cssResolver.AddCssFile(CSS_PATH, true);
// question missing this part - REGISTER the font(s)
var fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
// may need to add other web-fonts-with-css\webfonts\*.ttf depending on needs
fontProvider.Register(Path.Combine(FONT_PATH, "fa-solid-900.ttf"), "FontAwesome");
var cssAppliers = new CssAppliersImpl(fontProvider);
var htmlPipelineContext = new HtmlPipelineContext(cssAppliers);
htmlPipelineContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
var pdfWriterPipeline = new PdfWriterPipeline(document, writer);
var htmlPipeline = new HtmlPipeline(htmlPipelineContext, pdfWriterPipeline);
var cssResolverPipeline = new CssResolverPipeline(
cssResolver, htmlPipeline
);
var worker = new XMLWorker(cssResolverPipeline, true);
var parser = new XMLParser(worker);
using (var stringReader = new StringReader(XHTML))
{
parser.Parse(stringReader);
}
}
}
输出:
几点说明: