Welcome Guest Search | Active Topics | Sign In | Register

Repeating TH row of table on each page Options
garya
Posted: Friday, June 3, 2011 12:40:16 PM
Rank: Newbie
Groups: Member

Joined: 6/3/2011
Posts: 4
I am currently evaluating the product. I need to convert some HTML reports into PDF. The product looks good. At first I had a problem with the text in my table rows (TR element) being split right in the middle between two pages. I was able to get around this by using page-break-inside: avoid style on each tr element.

That is great, but my next problem, and this is a show-stopper based on my requirements, is that I would like the table header row (TH) to repeat at the beginning of each page. Is there any way to get the HTML conversion tool to do this for me?

Short of that, is there some way for me to do this manually through the low-level API?

Thanks,
Gary
eo_support
Posted: Friday, June 3, 2011 12:51:53 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi Gary,

We currently do not support automatically repeating TH on each page, however it is very easy to do it manually either through low-level API or additional calls to ConvertHtml with a small HTML snippet that is just the header row. The basic idea is:

1. Set HtmlToPdf.Options.OutputArea to extend the page top margin when you render your original table. This reserves extra room at the top of the page so that you can later "fill in" the table header on each page;
2. Call ConvertHtml with the full table but without the table header row because you will actually fill in the header later during a separate run;
3. From step 2 you would have a HtmlToPdfResult object. From that object you can find out detailed information about "where" the table is rendered, including from which page to which page, the size/height of each table row/cell, etc;
4. Now you should have a PdfDocument object, loop through each page and call ConvertHtml with the header HTML to fill the header in. You would need to set HtmlToPdf.Options.OutputArea again based on information from step 3. You can also use the low-level API to generate output for this step, depending on whichever way is easier for you;

Please let us know if this makes sense to you and feel free to let us know if you need more help.

Thanks!
garya
Posted: Friday, June 3, 2011 1:13:46 PM
Rank: Newbie
Groups: Member

Joined: 6/3/2011
Posts: 4
Thank you for the quick response. I will give that a try.

I did run into a new problem. Using page-break-inside: avoid seems to work if I only use it in in one row in the table, but when I add it to all of them, the converter ignores this and splits the rows in the middle again. Here is the test html that I am running through your demo program that is not using the page-break-inside style hint.

Code: HTML/ASPX
<html>
	<head>
		<title></title>
        <style type="text/css">
            body {
		font-family: verdana, arial, sans-serif;
		
		background: #ffffff;
		color: #333333;
		font-size: 95%;
		
}

            .report, #reportcontent {
                border-top: 0;
                margin: 1em 0.5em;
                padding: 0 0;
                font-size: 5em;    
                width: 700px;
            }
            
            td 
            {
                font-size: 5em;   
            }


        </style>
	</head>
	<body id="report">
    <h4>My Test</h4>
    <h3>Header</h3>
    <div id="reportcontent" class="report">
	    <table border="1">
            <thead>
                <tr style="page-break-inside: avoid;">
                    <td >Column 1</td>
                    <td >Column 2</td>
                    <td >Column 3</td>
                </tr>
            </thead>
            <tbody>
                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;" >
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
                                <tr style="page-break-inside: avoid;">
                    <td >test data column 1</td>
                    <td >test data column 2</td>
                    <td >test data column 3</td>
                </tr>
            </tbody>
        </table>
        </div>
	</body>
</html>

eo_support
Posted: Friday, June 3, 2011 1:20:33 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Thanks for the test page. We will look into it and get back to you as soon as possible.
eo_support
Posted: Friday, June 3, 2011 9:27:32 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

We have posted a new build that fixed the "page-break-inside: avoid" problem. You can download the new build from our download page.

Thanks!
garya
Posted: Monday, June 6, 2011 3:42:52 PM
Rank: Newbie
Groups: Member

Joined: 6/3/2011
Posts: 4
Thank you for the quick response. This fixed the immediate problem. As I am trying to implement this on my website I have found a few more oddities. I am working on getting the most simple sample that can be easily reproduced. The first issue is with using the cellspacing attribute of the html table. The following html code produces a table with only the header showing (again I'm using the EO.pdf demo program's convert Html option). If you remove the cellspacing attribute, it will work just fine. Unfortunately removing this on my real website did not fix my problem so I am still working on isolating the issue. On my website when I use page-break-inside: avoid on each TR element, it pushes the TR's to the second page and never puts in a page break at all. I will continue to try to isolate this issues and I will post again when I have found it. For now, here is the html that shows the cellspacing problem.

Thanks,
Gary
Code: HTML/ASPX
<html>
<body>
<div class="report">
<div class="reportsection">
    <table cellpadding="2" cellspacing="0">
	<thead>
	     <tr>
 		<td>col 1</td>
		<td>col 2</td>
		<td>col 3</td>
		<td>col 4</td>
		<td>col 5</td>
		<td>col 6</td>
		<td>col 7</td>
	     </tr>
	</thead>
	<tbody>
             <tr style="page-break-inside: avoid;">
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
             </tr>
             <tr style="page-break-inside: avoid;">
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
             </tr>
             <tr style="page-break-inside: avoid;">
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
             </tr>
             <tr style="page-break-inside: avoid;">
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
             </tr>
             <tr style="page-break-inside: avoid;">
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
             </tr>
             <tr style="page-break-inside: avoid;">
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
                    <td>TEST DATA</td>
             </tr>
	</tbody>
    </table>
</div>
</div>
</body>
</html>

eo_support
Posted: Monday, June 6, 2011 9:35:17 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

We have updated to build .44 that should fix this problem. You can download the new build from our download page.

Thanks!
garya
Posted: Wednesday, June 8, 2011 10:39:22 AM
Rank: Newbie
Groups: Member

Joined: 6/3/2011
Posts: 4
Great, thank you! The other issues I was having were due to some invalid CSS which I have corrected on my end, so it seems to be working well.

Is there any way to make the PDF's smaller? They are quite large when you consider that it is mostly just text. For example, one report I have in html is approximately 70k of html text and an image that is about 13k, but when I convert it to PDF it is 1.5 MB. The PDF is 5 pages long in case that matters, and I have implemented what you describe above, copying the header of the table from the first page and pasting it onto each additional page using a subsequent call to ConvertHtml.


Would you prefer it if I made a new thread for this question?

Thanks
Gary
eo_support
Posted: Wednesday, June 8, 2011 11:05:26 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Thanks for confirming that it works! Yes. We would prefer you to start a new thread for a new question in the future.

The PDF file size is something that can be optimized but it will largely depend on what's causing it. It's usually caused by one of the two things: images and font. If it is caused by image, then it is possible for you to replace the images as jpg images and that should reduce the file size significantly. If it is caused by font, then there usually isn't a lot you can do.

Currently our converter does not have an option to automatically save image as jpg (some other converters automatically save images as jpg but some people don't want that because jpg compression is lossy). We will add an option to allow you to explicitly specify whether you want to automatically do jpeg compression on images in the future.

It is possible for you to replace your image with jpgs even before we implement it as an option on our converter. The basic steps are:

1. Skip all images when you call ConvertHtml or ConvertUrl. This can be easily done by applying the following CSS on your page:

Code: CSS
img { visibility: hidden; }


This will skip all images but reserve space for all images. You can also run this as a test to see whether your file size is caused by the images. If the file size is significantly smaller without the images, then it is caused by your images;

2. ConvertHtml and ConvertUrl will return a HtmlToPdfResult object. From that object you can use one of the “result.HtmlDocument.GetElementXXXX” function to get your image “Element” object. That object will tell you where the image appears on the PDF output (page index, location, size, etc);

3. Construct an AcmImage object using a jpg image, then render that AcmImage at the location returned by step 2. The code would be something like this:

Code: C#
//Create an AcmRender for the page (returned by step 2)
AcmRender render = new AcmRender(page);

//Create an AcmImage object. Here you will need to load
//the image you wish to "fill in" into a System.Drawing.Image
//object. If that object is jpeg, then it will be saved as is in
//the PDF file
AcmImage image = new AcmImage(your_system_drawing_image_object);

//Use an AcmBlock to position the image. Here we assume
//we do not need to stretch the image
AcmBlock block = new AcmBlock(image);
block.Style.Left = X;
block.Style.Top = Y;

//"Fill in" the image
render.Render(image);


This should save the image as jpeg in your pdf file. If you have a lot of images, then it should reduce your file size significantly.

This method can also be used to fill in high quality image. So we have a sample in the demo project at All Demos -> Html to PDF -> Advanced -> High Resolution Images that demonstrates this technique. You can take a look of the source code of that sample to see how it works.

Hope this helps. Please feel free to let us know if you have any more questions.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.