html - iTextSharp HTML 到 PDF 的转换 - 无法更改字体

标签 html asp.net-mvc pdf fonts itext

我在 ASP.NET MVC5 应用程序中使用 iTextSharp (5.5.7.0) 从 HTML 创建一些 PDF 文档,但我无法更改字体。我已经尝试了几乎所有我能在 SO 或其他资源中找到的东西。

生成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;
        }
    }

实际的 HTML 包含在 renderedReport 字符串变量中(我有强类型的 .cshtml 文件,我使用 MVC Razor 引擎渲染它,然后返回字符串中的 HTML)。

我尝试注册一些特定的字体,但没有帮助。我还尝试在我的机器上注册所有字体(如上例所示),但这也无济于事。字体已加载我已经在 Debug模式下检查过了。

CSS 像这样嵌入到 HTML 文件中(在标题、样式标签中):

    body {
        font-size: 7px;
        font-family: Comic Sans MS;
    }

(为了测试,我决定使用 Comic Sans,因为我可以轻松识别它,实际上我对 Arial Unicode MS 更感兴趣)。

我实际上可以使用 CSS 中的 font-family 属性更改字体,但只能使用 iTextSharp 默认预加载的字体 - Times New Roman、Arial、Courier 和其他一些字体(Helvetica我认为)。 当我将其更改为 - Comic Sans 或其他未预加载的 iTextSharp 时,它会使用默认字体呈现(我会说是 Arial)。

我需要更改字体的原因是因为我渲染的 HTML 中有一些克罗地亚语字符 (ČĆŠĐŽčćšđž),而 PDF 中缺少这些字符,目前我认为主要原因是 - 字体。

我错过了什么?

最佳答案

完成这项工作的几件事。

首先,XMLWorkerHelper不使用 FontFactory默认情况下,您需要使用 ParseXHtml() 的重载之一这需要 IFontProvider .这两个重载都需要您指定 Stream对于 CSS 文件,但您可以只传递 null如果您的 CSS 存在于您的 HTML 文件中。幸好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>,那么换种说法听起来很奇怪你的 CSS 是 body{font-size: 7px;} ,将不会应用字体大小,因为您的 HTML 缺少 <body>标签。

第四,这是可选的,但通常更容易将 HTML 和 CSS 彼此分开指定,我将在下面的示例中这样做。

您的代码已完成 95%,因此只需进行一些调整,它就可以正常工作。我只是解析原始 HTML 和 CSS 而不是 View ,但您可以根据需要进行修改。请记住(我想你知道这一点)iTextSharp 不能处理 ASP.Net,只能处理 HTML,所以你需要确保你的 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);
                }
            }

            doc.Close();
        }
    }

    bytes = ms.ToArray();
}

关于html - iTextSharp HTML 到 PDF 的转换 - 无法更改字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34412993/

相关文章:

javascript - jQuery Rotator 是按字母顺序排列的,我怎样才能让它在我的主页上随机排列?

javascript - 数组未从 View MVC 传递到 Controller

c# - 如何向 Request.Form 集合添加值

android - 从 URL 打开 PDF

javascript - Telerik kendo ui 绘图 exportPDF 发送到服务器

python - 如何将 pdf 文件中的两页合并为一页

HTML:将文本放在中心

java - Spring MVC动态列表表单提交

html - 为什么边距在 html5 和溢出 :hidden? 的 Internet Explorer 中不起作用

asp.net-mvc - 在 ASP.Net MVC View 中显示/隐藏链接