1

I am trying to generate a multi-column PDF from HTML using iText for .NET. I am using CSS3 syntax to generate two columns.

And below code is not working for me.

CSS

column-count:2; 

C# Code

StringReader html = new StringReader(@"
<div style='column-count:2;'>Sample Text. Sample Text. Sample Text. Sample Text. 
Sample Text. Sample Text. Sample Text. Sample Text. Sample Text. Sample Text. 
Sample Text. Sample Text. Sample Text. Sample Text. Sample Text. Sample Text. 
Sample Text. Sample Text. </div>
");

        Document document = new Document();
        PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(@"d:\temp\xyz.pdf", FileMode.Create));
        document.Open();
        XMLWorkerHelper.GetInstance().ParseXHtml(
          writer, document, html
        );
        document.Close();

Please suggest what is issue in this code. Or is there any other HTML to PDF library available to fix this issue.

Joris Schellekens
  • 8,483
  • 2
  • 23
  • 54
Harvinder
  • 91
  • 2
  • 10

1 Answers1

0

The CSS property column-count is not supported in XML Worker, and it probably never will.

However, this doesn't mean that you can't display HTML in columns.

If you go to the official XML Worker documentation, you'll find the ParseHtmlObjects where we parse a large HTML file and render it to a PDF with two columns: walden5.pdf

This is done by parsing the HTML into an ElementList first:

// CSS
CSSResolver cssResolver =
        XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.autoBookmark(false);
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, end);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);

Once we have the list of Element objects, we can add them to a ColumnText object:

// step 1
Document document = new Document(PageSize.LEGAL.rotate());
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
// step 3
document.open();
// step 4
Rectangle left = new Rectangle(36, 36, 486, 586);
Rectangle right = new Rectangle(522, 36, 972, 586);
ColumnText column = new ColumnText(writer.getDirectContent());
column.setSimpleColumn(left);
boolean leftside = true;
int status = ColumnText.START_COLUMN;
for (Element e : elements) {
    if (ColumnText.isAllowedElement(e)) {
        column.addElement(e);
        status = column.go();
        while (ColumnText.hasMoreText(status)) {
            if (leftside) {
                leftside = false;
                column.setSimpleColumn(right);
            }
            else {
                document.newPage();
                leftside = true;
                column.setSimpleColumn(left);
            }
            status = column.go();
        }
    }
}
// step 5
document.close();

As you can see, you need to make some decisions here: you need to define the rectangles on the pages. You need to introduce new pages, etc...

Note: there is currently no C# port of this documentation. Please think of the Java code as if it were pseudo code.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165