iTextSharp HTML to PDF转换 - 无法更改字体 [英] iTextSharp HTML to PDF conversion - unable to change font

查看:438
本文介绍了iTextSharp HTML to PDF转换 - 无法更改字体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



PDF生成代码如下:

  public Byte [] GetRecordsPdf(RecordsViewModel模型)
{
var viewPath =〜/ Template / RecordTemplate.cshtml;
var renderedReport = RenderViewToString(viewPath,model);

FontFactory.RegisterDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Fonts));

使用(var ms = new MemoryStream())
{
using(var doc = new Document())
{
doc.SetPageSize PageSize.A4.Rotate());

using(var writer = PdfWriter.GetInstance(doc,ms))
{
doc.Open();

使用(var html = new MemoryStream(Encoding.Default.GetBytes(renderedReport)))
{
XMLWorkerHelper.GetInstance()。ParseXHtml(writer,doc,html,Encoding 。默认);
}

doc.Close();
}
}

var bytes = ms.ToArray();
返回字节;




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

我试图注册一些特定的字体,但是没有帮助。我也尝试在我的机器上注册所有的字体(如上面的例子所示),但也没有帮助。字体被加载我已经检查,在调试模式。

CSS嵌入在HTML文件(标题,样式标签)中,如下所示:

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





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

我实际上可以使用该字体系列来更改字体属性从CSS,但只能从默认情况下由iTextSharp预装的字体 - Times New Roman,Arial,Courier和其他一些(Helvetica我认为)。当我将其更改为 - Comic Sans或其他不预装iTextSharp呈现与默认字体(宋体我会说)。

我需要更改字体的原因是因为我在呈现的HTML(ČĆŠĐŽčćšđž)中有一些克罗地亚字符,这些字符在PDF中不存在,目前我认为主要原因是 - 字体。



我缺少什么?

解决方案

首先, XMLWorkerHelper 不会使用 FontFactory 默认情况下,您需要使用一个重载 ParseXHtml()来获取 IFontProvider 。这两个重载都要求你为一个CSS文件指定一个 Stream ,但是如果你的CSS存在,你可以传递 null 在您的HTML文件中。幸运的是, FontFactory 有一个静态属性,可以使用这个属性来调用 FontFactory.FontImp

  // **这个人** 
XMLWorkerHelper.GetInstance()。ParseXHtml(writer,doc,msHTML,null,Encoding.UTF8,FontFactory .FontImp);

其次,我知道你说过你试图在绝望的时候注册你的整个字体目录,是一个相当昂贵的电话。如果可以的话,总是试着只注册你需要的字体。虽然是可选的,但我也强烈建议你明确地定义字体的别名,因为字体可以有多个名字,并不总是我们想象的那样。

 <$ c。c> 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,但你可以根据需要进行修改。请记住(我想你知道这个),iTextSharp不能处理ASP.Net,只有HTML,所以你需要确保你的ASP.Net到HTML的转换过程是理智的。

  //示例HTML和CSS 
var html = @< body>< p> Sva ljudskabićarađajuse slobodna我喜欢这个名字,我喜欢这个名字,我喜欢这个名字,我喜欢这个名字。
var css =body {font-size:7px; font-family:Comic Sans MS;};

//注册一个字体
FontFactory.Register(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts),comic.ttf),Comic Sans MS) ;

//占位符变量用于以后
字节[]字节;

使用(var ms = new MemoryStream()){
using(var doc = new Document()){
doc.SetPageSize(PageSize.A4.Rotate()) ;

using(var writer = PdfWriter.GetInstance(doc,ms)){
doc.Open();

//使用(var msHTML = new MemoryStream(Encoding.UTF8.GetBytes(html))){

//获取我们的HTML
流//获取使用(var msCSS = new MemoryStream(Encoding.UTF8.GetBytes(css))){

XMLWorkerHelper.GetInstance()。ParseXHtml(writer,doc,msHTML, msCSS,Encoding.UTF8,FontFactory.FontImp);
}
}

doc.Close();
}
}

bytes = ms.ToArray();
}


I'm creating some PDF documents with iTextSharp (5.5.7.0) from HTML in ASP.NET MVC5 application, but I'm unable to change the font. I've tried almost everything that I was able to find on SO or from some other resources.

Code for PDF generation is as follows:

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

Actual HTML is contained in renderedReport string variable (I have strongly typed .cshtml file which I render using MVC Razor engine and then return HTML in string).

I've tried to register some specific fonts, but that didn't help. I've also tried to register all fonts on my machine (as shown in example above), but that also didn't help. The fonts were loaded I've checked that in debug mode.

CSS is embedded in HTML file (in heading, style tag) like this:

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

(for test, I've decided to use Comic Sans, because I can recognize it with ease, I'm more interested in Arial Unicode MS actually).

And I'm actually able to change the font with that font-family attribute from CSS, but only from fonts that are preloaded by iTextSharp by default - Times New Roman, Arial, Courier, and some other (Helvetica i think). When I change it to - Comic Sans, or some other that is not preloaded iTextSharp renders with default font (Arial I would say).

The reason why I need to change the font is because I have some Croatian characters in my rendered HTML (ČĆŠĐŽčćšđž) which are missing from PDF, and currently I think the main reason is - font.

What am I missing?

解决方案

A couple of things to make this work.

First, XMLWorkerHelper doesn't use FontFactory by default, you need to use one of the overloads to ParseXHtml() that takes an IFontProvider. Both of those overloads require that you specify a Stream for a CSS file but you can just pass null if your CSS lives inside your HTML file. Luckily FontFactory has a static property that implements this that you can use called FontFactory.FontImp

//                                                                                 **This guy**
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHTML, null, Encoding.UTF8, FontFactory.FontImp);

Second, I know that you said that you tried registering your entire font directory out of desperation but that can be a rather expensive call. If you can, always try to just register the fonts you need. Although optional, I also strongly recommend that you explicitly define the font's alias because fonts can have several names and they're not always what we think.

FontFactory.Register(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "comic.ttf"), "Comic Sans MS");

Third, and this might not affect you, but any tags not present in the HTML, even if they're logically implied, won't get styling applied to them from CSS. That sounds weird so to say it differently, if your HTML is just <p>Hello</p> and your CSS is body{font-size: 7px;}, the font size won't get applied because your HTML is missing the <body> tag.

Fourth, and this is optional, but usually its easier to specify your HTML and CSS separately from each other which I'll do in the example below.

Your code was 95% there so with just a couple of tweaks it should work. Instead of a view I'm just parsing raw HTML and CSS but you can modify as needed. Please do remember (and I think you know this) that iTextSharp cannot process ASP.Net, only HTML, so you need to make sure that your ASP.Net to HTML conversion process is sane.

//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();
}

这篇关于iTextSharp HTML to PDF转换 - 无法更改字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆