I’m using ITextSharp to convert an HTML document into PDF. I use HTMLWorker.ParseToList and loop through each item in turn. That works fine, however the first page is required to have different margin sizes to the subsequent pages. I can do this by calling MyDocument.NewPage() and calling MyDocument.SetMargins().
My problem occurs when trying to detect the page transitions.
I can use a loop to keep track of page transitions, then call NewPage() and reset the margins, however, this can only happen once I’ve actually added a paragraph that wraps onto a new page, leaving an entire page that’s practically white-space.
I need a way of pre-emptively detecting if the page will change if I add a certain Paragraph object.
I’ve tried using ColumnText.Go(true) to simulate it (and if the result of that is ColumnText.NO_MORE_COLUMN, then make it a page break), unfortunately that appears to be flakey at best, and tends to detect page breaks in entirely the wrong places.
Here’s my current code:
ColumnText simulation = new ColumnText(Writer.DirectContent);
simulation.SetSimpleColumn(Writer.PageSize);
bool FirstPage = true;
foreach (var item in ItemList)
{
var para = new Paragraph("", Normal);
para.AddAll(item.Chunks);
para.SpacingAfter = 10;
foreach (Chunk c in item.Chunks)
{
simulation.AddText(c);
}
if(FirstPage) {
int simresult = simulation.Go(true);
if(simresult == (int)ColumnText.NO_MORE_COLUMN)
{
textDocument.SetMargins(100,100,100,100);
textDocument.NewPage();
FirstPage = false;
}
}
textDocument.Add(para);
}
This results in it not detecting a page break until the end of page 2. Which is no good.
The only way I’ve found to get it working is to HALF the height going into simulation.SetSimpleColumn.
It works, but I don’t know why, and honestly, that’s no good. If anyone can give me any insight that’d be great.
Thanks to Alexis I’ve worked it out. The ITextSharp follows the Java event model pretty thoroughly, which is annoying since I was looking for events in the Writer and Document directly.
First I had to create a class that overrode PdfPageEventHelper:
internal class MainTextEventsHandler : PdfPageEventHelper
{
public override void OnStartPage(PdfWriter writer, Document document)
{
document.SetMargins(document.LeftMargin, document.LeftMargin, document.TopMargin, document.BottomMargin); //Mirror the horizontal margins
document.NewPage(); //do this otherwise the margins won't take
}
}
Next, I set the PageEvent property of the Writer object, and I modified my loop to remove the simulation.
Writer.PageEvent = new MainTextEventsHandler();
foreach (var item in ItemList)
{
var para = new Paragraph("", Normal);
para.AddAll(item.Chunks);
/* per-paragraph stuff here */
para.SpacingAfter = 10;
textDocument.Add(para);
}
Have a look at Page Events, in particular onStartPage and/or onEndPage to determine if you have to change the margins of the document.
Please note that these examples are for the Java version, but the conversion to iTextSharp should be straightforward.