iTextSharp中缺少字体真棒图标pdf

时间:2018-05-08 19:20:29

标签: c# pdf vue.js itext font-awesome

我正在尝试使用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">&#xf07a;</i> Print Order

1 个答案:

答案 0 :(得分:2)

iText对Font Awesome有知识,所以你需要做更多的工作。以下是简单的测试/工作示例。

HTML:

<html>
<head>
<style>
.fas { font-family: FontAwesome; color:green; }
</style>
</head>
<body>
<i class='fas'>&#xf07a;</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);
        }
    }
}

输出:

enter image description here

几点说明:

  • 没有尝试过,但使用了Font Awesome特定的unicode。带有Font Awesome特定类的空Html节点对我来说没有用。
  • iText CSS解析器非常基本,所以尽量保持简单,就像上面的HTML片段一样。