C# 未使用 iTextSharp 将 CSS 样式应用于 PDF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18131992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:23:37  来源:igfitidea点击:

CSS styles not being applied to PDF with iTextSharp

c#pdf-generationitextsharp

提问by Broodmdh

I am attempting to convert a portion of my webpage to pdf using iTextSharp, and while the pdf generation is working correctly, none of the css styles are being applied. I've tried applying the styles one at a time, but that doesn't seem to work. This is what I've come up with so far:

我正在尝试使用 iTextSharp 将我的网页的一部分转换为 pdf,虽然 pdf 生成工作正常,但没有应用任何 css 样式。我试过一次应用一种样式,但这似乎不起作用。这是我到目前为止想出的:

//Get the portion of the page to convert.
StringBuilder sb = new StringBuilder();
print_div.RenderControl(new HtmlTextWriter(new StringWriter(sb)));
string html = sb.ToString();

//Generate a random filename to use for the pdf
Guid random_guid;
random_guid = Guid.NewGuid();
string fileName = random_guid.ToString() + ".pdf";
string filename_with_folder = @"pdf\sl_" + fileName;
string fullFilePath = System.IO.Path.Combine(Request.PhysicalApplicationPath, filename_with_folder);

using (Document doc = new Document())
{
    // Create the pdf
    PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(fullFilePath, FileMode.Create));
    doc.Open();
    try
    {
        //Set the font size for all elements
        StyleSheet styles = new StyleSheet();
        styles.LoadStyle("body", "fontsize", "8px");

        //Write the content to the pdf document
        StringReader sr = new StringReader(html);
        XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, sr);
    }
    catch (Exception ex)
    {
    }
    doc.Close();
}

Am I missing something? I started off using HTMLWorker and have switched to XMLWorker, but I think I'm just confusing myself now. Help would be appreciated.

我错过了什么吗?我开始使用 HTMLWorker 并切换到 XMLWorker,但我想我现在只是让自己感到困惑。帮助将不胜感激。

ATTEMP #2

尝试#2

Thanks for the reply! This is what I've come up with, but it isn't working. My content doesn't appear in the pdf at all now, and I'm not sure why. Any thoughts?

谢谢回复!这是我想出来的,但它不起作用。我的内容现在根本没有出现在 pdf 中,我不知道为什么。有什么想法吗?

using (Document doc = new Document())
{
    PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(fullFilePath, FileMode.Create));
    doc.Open();

    // CSS
    var cssResolver = new StyleAttrCSSResolver();
    var cssFile = XMLWorkerHelper.GetCSS(new FileStream(HttpContext.Current.Server.MapPath("~/css/print.css"), FileMode.Open));
    cssResolver.AddCss(cssFile);

    // HTML
    CssAppliers ca = new CssAppliersImpl();
    HtmlPipelineContext hpc = new HtmlPipelineContext(ca);
    hpc.SetTagFactory(Tags.GetHtmlTagProcessorFactory());

    // PIPELINES
    PdfWriterPipeline pdf = new PdfWriterPipeline(doc, writer);
    HtmlPipeline htmlPipe = new HtmlPipeline(hpc, pdf);
    CssResolverPipeline css = new CssResolverPipeline(cssResolver, htmlPipe);

    XMLWorker worker = new XMLWorker(css, true);
    XMLParser p = new XMLParser(worker);
    StringReader sr = new StringReader(html);
    p.Parse(sr);
    doc.Close();
}

Am I close, or am I missing the point completely?

我很接近,还是我完全没有抓住重点?

回答by SShakeri

You can create the XmlWorker using a CSSResolver

您可以使用 CSSResolver 创建 XmlWorker

var cssResolver = new StyleAttrCSSResolver();
//Change the path to your CSS file
var cssFile = XMLWorkerHelper.GetCSS(new FileStream(HttpContext.Current.Server.MapPath("~/pdf.css"), FileMode.Open));
cssResolver.AddCss(cssFile);

And then create your HtmlPipeline and pass it to the CssResolverPipeline constructor:

然后创建您的 HtmlPipeline 并将其传递给 CssResolverPipeline 构造函数:

CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker); 
using (TextReader sr = new StringReader(html))
        {
            p.Parse(sr);
            document.Close();
        }
        //close your writer
        pdfwriter.Close();

回答by kolin

Not sure if you managed to work around this problem, but I had the same issue of CSS styles not being applied in my question "Cannot get CSS to work in iTextSharp (5.4.3) when making pdf" here on SO.

不确定您是否设法解决了这个问题,但我在我的问题“制作 pdf 时无法让 CSS 在 iTextSharp (5.4.3) 中工作”时遇到了同样的 CSS 样式问题。

Basically I found that some parts of the stylesheet were being applied (for example, borders around table cells) but others not (colour of fonts, sizes of anything not being in PX)

基本上我发现样式表的某些部分正在被应用(例如,表格单元格周围的边框)但其他部分没有(字体颜色,任何不在 PX 中的大小)

回答by Agus Rdz

In order to use stylesheets to create a PDF file with XmlWorker you can try this example code that returns a byte array.

为了使用样式表通过 XmlWorker 创建 PDF 文件,您可以试试这个返回字节数组的示例代码。



        byte[] bytesArray = null;
        using (var ms = new MemoryStream())
        {
            using (var document = new Document())
            {
                using (PdfWriter writer = PdfWriter.GetInstance(document, ms))
                {
                    document.Open();
                    using (var strReader = new StringReader(html))
                    {
                        //Set factories
                        HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
                        htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
                        //Set css
                        ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
                        cssResolver.AddCssFile(System.Web.HttpContext.Current.Server.MapPath("~/Content/bootstrap.min.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;