0

I am converting my HTML Table to PDF:

using (MemoryStream stream = new System.IO.MemoryStream())
{
    StringReader sr = new StringReader(GridHtml);
    Document pdfDoc = new Document(PageSize.A0, 10f, 10f, 10f, 0f);
    PdfWriter writer = PdfWriter.GetInstance(pdfDoc, stream);
    pdfDoc.Open();
    XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
    pdfDoc.Close();
    return File(stream.ToArray(), "application/pdf", "Grid.pdf");
}

This works fine but I have some white-space (nowrap) after conversion.

How can I have no wrap on the <td> of my HTML table?

And also my table is very long, it has a lot of columns. What would be the best to extend the page or best practice for having a long table in width when its very long horizontally?

Here is GridHtml:

https://jsfiddle.net/2nyjhpaz/

user979331
  • 11,039
  • 73
  • 223
  • 418

2 Answers2

1

As far as I understand you work with iText5 and there might be troubles with recognising white-space: nowrap anyway and therefore it's possible to set your table preferences going through all the cells in your code after obtaining the table from the page elements:

// Setting a css file
ICSSResolver cssResolver = new StyleAttrCSSResolver();
ICssFile cssFile = XMLWorkerHelper.GetCSS(cssStream);
cssResolver.AddCss(cssFile);

// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());

// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline pdf = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);

CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
// Transmitting the html file with the table
p.Parse(htmlStream);

// Obtaining the table
var table = elements[0];
var pdfTable = table as PdfPTable;

foreach (var c in pdfTable.Rows.SelectMany(r => r.GetCells()))
{
    c.NoWrap = true;
}

Here is the link to the official documentation (though there are only examples written in JAVA) which I applied to my example. The problem with the approach is that you're likely to be responsible for dealing with your cell widths like this (How to define the width of a cell? ):

 pdfTable.SetTotalWidth(new float[] { 500, 500, 500, 500, 500 });
 pdfTable.LockedWidth = true;

Otherwise the cells might overlap with one another.

To define your page size in accordance to the table width and height you can do it the next way (How to define the page size based on the content?):

var pdfDoc = new Document(new Rectangle(pdfTable.TotalWidth, pdfTable.TotalHeight), 10f, 10f, 10f, 0f);
Oleg Safarov
  • 2,325
  • 14
  • 19
  • What is cssStream? what does it look like? – user979331 Feb 26 '18 at 04:42
  • In this particular case it's just a stream of a resource in my test project containing all the styles for my html stream (I also store it as an embedded resource). I set it the next way: `var assembly = Assembly.GetExecutingAssembly(); var cssStream = assembly.GetManifestResourceStream("PDFCreatorTestProject.styles.css"); var htmlStream = assembly.GetManifestResourceStream("PDFCreatorTestProject.table.html");` – Oleg Safarov Feb 26 '18 at 08:24
  • You can avoid storing all your data in resources and get streams directly from strings like this: `var css = ""; ICSSResolver cssResolver = new StyleAttrCSSResolver(); ICssFile cssFile; using (MemoryStream cssStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(css))) { cssFile = XMLWorkerHelper.GetCSS(cssStream); } cssResolver.AddCss(cssFile);` The same way is possible for `htmlStream`. – Oleg Safarov Feb 26 '18 at 08:30
  • Okay, ill give this a try – user979331 Feb 26 '18 at 13:44
  • I am stuck on this part: p.Parse(htmlStream); how would I define htmlStream using my variable GridHtml? – user979331 Feb 26 '18 at 14:53
  • It depends on what `GridHtml` is. If it's just a string then you should do it the same way as I depicted above, like this: `using (MemoryStream htmlStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(GridHtml))) { p.Parse(htmlStream); }` – Oleg Safarov Feb 26 '18 at 15:18
  • Actually, you can do it in a way equal to your own example, that is to say, through the usage of `PdfWriter`: `var pdfWriter = PdfWriter.GetInstance(pdfDoc, stream); pdfDoc.Open(); pdfDoc.Add(pdfTable); pdfDoc.Close();`, where `stream` is any kind of stream: `FileStream` or `MemoryStream` - it's up to you. – Oleg Safarov Feb 26 '18 at 16:01
  • So define stream as `MemoryStream stream = new System.IO.MemoryStream()` – user979331 Feb 26 '18 at 16:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165847/discussion-between-user979331-and-oleg-safarov). – user979331 Feb 26 '18 at 16:34
  • This is working very well....But I am having trouble setting the cell width...is there away to set the cell width to all cells? or better yet, apply 1 size to first row of cells and the another width for all other cells? – user979331 Feb 26 '18 at 18:13
0

Use HTML <td> nowrap Attribute

<td nowrap>No wrapped</td>

The nowrap attribute of is not supported in HTML5. Use CSS instead.
CSS syntax: <td style="white-space: nowrap">

Test example is here https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_td_nowrap.


What would be the best to extend the page?

You can use Rotate() to landscape the page here:

iTextSharp.text.Document doc;

// ...initialize 'doc'...

// Set the page size
doc.SetPageSize(iTextSharp.text.PageSize.A4.Rotate());

Or use RectangleReadOnly for setting the size of height and width:

Document doc = new Document(new RectangleReadOnly(595,842,90), 88f, 88f, 10f, 10f);
Community
  • 1
  • 1