2

I am trying to generate PDF from below HTML i.e. a text with dotted underline. (Below is sample actual HTML is much bigger)

<u style="border-bottom: 1px dotted #000;text-decoration: none;"> Hello </u>

as explained in How to convert HTML to PDF using iTextSharp . The output is supposed to have a dotted line which I can see in the HTML file, however the PDF generated by iTextSharp shows a normal underline and not a dotted underline. Here is my complete method

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

I even tried other methods like below code still I see a PDF generated with a normal underline as opposed to a dotted underline. What I am missing here ?

                    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);
                        }
                    }
Community
  • 1
  • 1
Ravi A.
  • 2,163
  • 2
  • 18
  • 26

1 Answers1

0

According to the CSS conformance list, borders are only supported on table cells.

The line you are seeing is actually the <u> tag's default bottom border and your text-decoration code is actually being overwritten by the default code for a <u> tag. If you watch the ResolveStyles method in iTextSharp\tool\xml\css\StyleAttrCSSResolver.cs, the top chunk (around 170 in 5.5.6) that sets keys and values for tagCss correctly finds and sets your property. The next block of code after that, however, special-cases certain HTML tags and forces some rules upon then.

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

Since this block happens after your CSS you'll see that you can't remove an underline on a <u> tag because it will always be turned back on. Similarly, you also can't un-bold a <strong> tag, un-italic an <em> or explicitly set a font size on a <big> tag (I forgot that was actually a tag!) unless you have a parent container's font size set.

So unfortunately, short of modifying the source I'm not really sure that what you are looking for is possible.

Chris Haas
  • 53,986
  • 12
  • 141
  • 274
  • Thank you for the update Chris. I tried using different HTML tags but still the issue is there. For example with
     Hello stackoverflow how are you? 
    . Any suggestions ? I think I will go with your other suggestion as mentioned in http://stackoverflow.com/questions/29260730/how-do-you-underline-text-with-dashedline-in-itext-pdf and I will mix my HTML accordingly.
    – Ravi A. Jul 13 '15 at 16:01
  • Like I said, you can only change the border style on a table cell, nothing else, so a div wouldn't help you. You'll need to mix it with the other one (that I forgot I wrote about even!) – Chris Haas Jul 13 '15 at 17:06