C# 使用iTextSharp将HTML样式(虚线下划线)转换为PDF

C# 使用iTextSharp将HTML样式(虚线下划线)转换为PDF,c#,html,pdf,itextsharp,C#,Html,Pdf,Itextsharp,我试图从下面的HTML生成PDF,即带点下划线的文本。(下面是示例,实际HTML要大得多) 你好 如中所述。输出应该有一条虚线,我可以在HTML文件中看到,但是由iTextSharp生成的PDF显示的是普通下划线,而不是虚线下划线。这是我的完整方法 public void UsingXMLWorker() { Byte[] bytes; //Create a stream that we can write to, in

我试图从下面的HTML生成PDF,即带点下划线的文本。(下面是示例,实际HTML要大得多)

你好 如中所述。输出应该有一条虚线,我可以在HTML文件中看到,但是由iTextSharp生成的PDF显示的是普通下划线,而不是虚线下划线。这是我的完整方法

   public void UsingXMLWorker()
    {            
        Byte[] bytes;

        //Create a stream that we can write to, in this case a MemoryStream
        using (var ms = new MemoryStream())
        {

            using (var doc = new Document())
            {
                //Create a writer that's bound to our PDF abstraction and our stream
                using (var writer = PdfWriter.GetInstance(doc, ms))
                {

                    //Open the document for writing
                    doc.Open();

                    //sample HTML and CSS
                    var example_html = @"<u style=""border-bottom: 1px dotted #000;text-decoration: none;"" >&nbsp;Hello&nbsp;</u>";

                    using (var srHtml = new StringReader(example_html))
                    {
                        //Parse the HTML
                        iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
                    }

                    //var example_html = @"<u class=""dottedBorder"">&nbsp;Hello&nbsp;</u>";
                    //var example_css = @".dottedBorder{border-bottom: 1px dotted #000;text-decoration: none;font-size:38px;}";
                    //using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css)))
                    //{
                    //    using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html)))
                    //    {

                    //        //Parse the HTML
                    //        iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss);
                    //    }
                    //}
                    doc.Close();
                }
            }
            bytes = ms.ToArray();
        }


        var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
        System.IO.File.WriteAllBytes(testFile, bytes);
    }
使用XMLWorker()的公共作废 { 字节[]字节; //创建一个我们可以写入的流,在本例中是一个MemoryStream 使用(var ms=new MemoryStream()) { 使用(var doc=new Document()) { //创建一个绑定到PDF抽象和流的编写器 使用(var writer=PdfWriter.GetInstance(doc,ms)) { //打开文档进行写作 doc.Open(); //示例HTML和CSS var示例_html=@“你好”; 使用(var srHtml=newstringreader(示例_html)) { //解析HTML iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer、doc、srHtml); } //var示例_html=@“你好”; //var example_css=@“.dottedBorder{边框底部:1px点#000;文本装饰:无;字体大小:38px;}”; //使用(var msCss=newmemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css))) //{ //使用(var msHtml=newmemoryStream(System.Text.Encoding.UTF8.GetBytes(示例_html))) // { ////解析HTML //iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer、doc、msHtml、mscs); // } //} doc.Close(); } } 字节=ms.ToArray(); } var testFile=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),“test.pdf”); System.IO.File.writealBytes(testFile,字节); } 我甚至尝试了其他方法,比如下面的代码,但我看到的PDF是用普通下划线而不是虚线下划线生成的。我错过了什么

                    var example_html = @"<u class=""dottedBorder"">&nbsp;Hello&nbsp;</u>";
                    var example_css = @".dottedBorder{border-bottom: 1px dotted #000;text-decoration: none;font-size:38px;}";
                    using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css)))
                    {
                        using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html)))
                        {

                            //Parse the HTML
                            iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss);
                        }
                    }
var示例_html=@“你好”;
var example_css=@“.dottedBorder{边框底部:1px点#000;文本装饰:无;字体大小:38px;}”;
使用(var msCss=newmemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css)))
{
使用(var msHtml=newmemoryStream(System.Text.Encoding.UTF8.GetBytes(示例_html)))
{
//解析HTML
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer、doc、msHtml、mscs);
}
}
根据,只有表格单元格支持边框

您看到的行实际上是
标记的默认底部边框,您的
文本装饰
代码实际上被
标记的默认代码覆盖。如果查看
iTextSharp\tool\xml\css\StyleAttrCSSResolver.cs
中的
ResolveStyles
方法,为
tagCss
设置键和值的顶部块(5.5.6中约170个)将正确查找并设置属性。然而,在这之后的下一段代码中,有一些特殊情况需要使用特定的HTML标记并强制使用一些规则

// inherit css from parent tags, as defined in provided CssInheritanceRules or if property = inherit
IDictionary<String, String> css = t.CSS;
if (t.Name != null)
{
    if (t.Name.Equals(HTML.Tag.I) || t.Name.Equals(HTML.Tag.CITE)
        || t.Name.Equals(HTML.Tag.EM) || t.Name.Equals(HTML.Tag.VAR)
        || t.Name.Equals(HTML.Tag.DFN) || t.Name.Equals(HTML.Tag.ADDRESS)) {
            tagCss[CSS.Property.FONT_STYLE] = CSS.Value.ITALIC;
    }
    else if (t.Name.Equals(HTML.Tag.B) || t.Name.Equals(HTML.Tag.STRONG)) {
        tagCss[CSS.Property.FONT_WEIGHT] = CSS.Value.BOLD;
    }
    else if (t.Name.Equals(HTML.Tag.U) || t.Name.Equals(HTML.Tag.INS)) {
        tagCss[CSS.Property.TEXT_DECORATION] = CSS.Value.UNDERLINE;
    }
    else if (t.Name.Equals(HTML.Tag.S) || t.Name.Equals(HTML.Tag.STRIKE) 
             || t.Name.Equals(HTML.Tag.DEL)) {
                 tagCss[CSS.Property.TEXT_DECORATION] = CSS.Value.LINE_THROUGH;
    }
    else if (t.Name.Equals(HTML.Tag.BIG)) {
        tagCss[CSS.Property.FONT_SIZE] = CSS.Value.LARGER;
    }
    else if (t.Name.Equals(HTML.Tag.SMALL)) {
        tagCss[CSS.Property.FONT_SIZE] = CSS.Value.SMALLER;
    }
}
//根据提供的CssInheritanceRules中的定义或如果property=inherit,从父标记继承css
IDictionary css=t.css;
if(t.Name!=null)
{
if(t.Name.Equals(HTML.Tag.I)| t.Name.Equals(HTML.Tag.CITE)
||t.Name.Equals(HTML.Tag.EM)| t.Name.Equals(HTML.Tag.VAR)
||t.Name.Equals(HTML.Tag.DFN)| | t.Name.Equals(HTML.Tag.ADDRESS)){
tagCss[CSS.Property.FONT\u STYLE]=CSS.Value.ITALIC;
}
else if(t.Name.Equals(HTML.Tag.B)| | t.Name.Equals(HTML.Tag.STRONG)){
tagCss[CSS.Property.FONT\u WEIGHT]=CSS.Value.BOLD;
}
else if(t.Name.Equals(HTML.Tag.U)| | t.Name.Equals(HTML.Tag.INS)){
tagCss[CSS.Property.TEXT_DECORATION]=CSS.Value.UNDERLINE;
}
else if(t.Name.Equals(HTML.Tag.S)| | t.Name.Equals(HTML.Tag.STRIKE)
||t.Name.Equals(HTML.Tag.DEL)){
tagCss[CSS.Property.TEXT\u DECORATION]=CSS.Value.LINE\u-THROUGH;
}
else if(t.Name.Equals(HTML.Tag.BIG)){
tagCss[CSS.Property.FONT\u SIZE]=CSS.Value.LARGER;
}
else if(t.Name.Equals(HTML.Tag.SMALL)){
tagCss[CSS.Property.FONT\u SIZE]=CSS.Value.更小;
}
}
由于此块发生在CSS之后,您将看到无法删除
标记上的下划线,因为它将始终处于打开状态。类似地,除非设置了父容器的字体大小,否则也不能对
标记取消加粗,对
标记取消斜体,或在
标记上显式设置字体大小(我忘了那实际上是一个标记!)


不幸的是,除了修改源代码之外,我不确定您要查找的是否可行。

谢谢您的更新。我尝试使用不同的HTML标记,但问题仍然存在。例如,你好吗。有什么建议吗?我想我会同意你在中提到的其他建议,我会相应地混合我的HTML。就像我说的,你只能更改表格单元格上的边框样式,其他什么都不能,所以div对你没有帮助。你需要把它和另一个(我甚至都忘了我写过这个!)
// inherit css from parent tags, as defined in provided CssInheritanceRules or if property = inherit
IDictionary<String, String> css = t.CSS;
if (t.Name != null)
{
    if (t.Name.Equals(HTML.Tag.I) || t.Name.Equals(HTML.Tag.CITE)
        || t.Name.Equals(HTML.Tag.EM) || t.Name.Equals(HTML.Tag.VAR)
        || t.Name.Equals(HTML.Tag.DFN) || t.Name.Equals(HTML.Tag.ADDRESS)) {
            tagCss[CSS.Property.FONT_STYLE] = CSS.Value.ITALIC;
    }
    else if (t.Name.Equals(HTML.Tag.B) || t.Name.Equals(HTML.Tag.STRONG)) {
        tagCss[CSS.Property.FONT_WEIGHT] = CSS.Value.BOLD;
    }
    else if (t.Name.Equals(HTML.Tag.U) || t.Name.Equals(HTML.Tag.INS)) {
        tagCss[CSS.Property.TEXT_DECORATION] = CSS.Value.UNDERLINE;
    }
    else if (t.Name.Equals(HTML.Tag.S) || t.Name.Equals(HTML.Tag.STRIKE) 
             || t.Name.Equals(HTML.Tag.DEL)) {
                 tagCss[CSS.Property.TEXT_DECORATION] = CSS.Value.LINE_THROUGH;
    }
    else if (t.Name.Equals(HTML.Tag.BIG)) {
        tagCss[CSS.Property.FONT_SIZE] = CSS.Value.LARGER;
    }
    else if (t.Name.Equals(HTML.Tag.SMALL)) {
        tagCss[CSS.Property.FONT_SIZE] = CSS.Value.SMALLER;
    }
}