Itextsharp nextcolumn not working
I am trying to create a simple page with two columns, write to the first column, then the second. However, the code below puts both paragraphs in the second column. The current column of the column looks correct (first 0, then 1)
Any ideas what I am doing wrong?
MultiColumnText columns = new MultiColumnText();
columns.AddSimpleColumn(0, 200);
columns.AddSimpleColumn(200, 400);
Paragraph para1 = new Paragraph("Para1");
columns.AddElement(para1);
Response.Write(columns.CurrentColumn);//traces 0
columns.NextColumn();
Response.Write(columns.CurrentColumn);//traces 1
Paragraph para2 = new Paragraph("Para2");
columns.AddElement(para2);
doc.Add(columns);
Many thanks
Oliver
source to share
I have not been able to get NextColumn()
to work with the object MultiColumnText
, and I have not been able to find any samples (in .NET) that do.
A MultiColumnText
makes it easier to create columns in a document, but in return you give up a lot of control over the layout. You can use an object ColumnText
that gives you a lot of control over the layout of the columns, but requires more code.
Here is a simple but complete example of what you are trying to do using ColumnText
:
private void TestColumnText() {
using (FileStream fs = new FileStream("ColumnTest.pdf", FileMode.Create)) {
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
doc.Open();
PdfContentByte cb = writer.DirectContent;
ColumnText ct = new ColumnText(cb);
float columnWidth = 200f;
float[] left1 = { doc.Left + 90f, doc.Top - 80f, doc.Left + 90f, doc.Top - 170f, doc.Left, doc.Top - 170f, doc.Left, doc.Bottom };
float[] right1 = { doc.Left + columnWidth, doc.Top - 80f, doc.Left + columnWidth, doc.Bottom };
float[] left2 = { doc.Right - columnWidth, doc.Top - 80f, doc.Right - columnWidth, doc.Bottom };
float[] right2 = { doc.Right, doc.Top - 80f, doc.Right, doc.Bottom };
// Add content for left column.
ct.SetColumns(left1, right1);
ct.AddText(new Paragraph("Para 1"));
ct.Go();
// Add content for right column.
ct.SetColumns(left2, right2);
ct.AddText(new Paragraph("Para 2"));
ct.Go();
doc.Close();
}
}
Warning . As I mentioned, this is a simple example and will not even serve as a starting point for what you are trying to do. The samples on the sites below (especially the first one) will help you:
http://www.mikesdotnetting.com/Article/89/iTextSharp-Page-Layout-with-Columns http://www.devshed.com/c/a/Java/Adding-Columns-With-iTextSharp
source to share
As I found out that the latest versions of iTextSharp do not include a class MultiColumnText
, I created one of my own types.
Public Class SimpleColumnText
Inherits ColumnText
Dim workingDocument As Document
Dim columns As New List(Of Rectangle)
Dim currentColumn As Integer = 0
Public Sub New(content As PdfContentByte, columnCount As Integer, columnSpacing As Single, document As Document)
MyBase.New(content)
workingDocument = document
CalculateColumnBoundries(columnCount, columnSpacing)
End Sub
Private Sub CalculateColumnBoundries(columnCount As Integer, columnSpacing As Single)
Dim columnWidth As Single
Dim columnHeight As Single
With workingDocument
columnWidth = ((.PageSize.Width - .LeftMargin - .RightMargin) - (columnSpacing * (columnCount - 1))) / columnCount
columnHeight = (.PageSize.Height - .TopMargin - .BottomMargin)
End With
For x = 0 To columnCount - 1
Dim llx As Single = ((columnWidth + columnSpacing) * x) + workingDocument.LeftMargin
Dim lly As Single = workingDocument.BottomMargin
Dim urx As Single = llx + columnWidth
Dim ury As Single = columnHeight
Dim newRectangle As New Rectangle(llx, lly, urx, ury)
columns.Add(newRectangle)
Next
End Sub
Public Shadows Sub AddElement(element As IElement)
MyBase.AddElement(element)
'we have to see if there is a column on the page before we begin
Dim status As Integer
If currentColumn = 0 Then
status = ColumnText.NO_MORE_COLUMN
End If
Do
If status = ColumnText.NO_MORE_COLUMN Then
If currentColumn = columns.Count Then
'we need a new page
workingDocument.NewPage()
'reset column count
currentColumn = 0
End If
MyBase.SetSimpleColumn(columns(currentColumn))
currentColumn += 1
End If
status = MyBase.Go()
Loop While ColumnText.HasMoreText(status)
End Sub
End Class
This can be easily expanded to Shadow
other functions in ColumnText
.
source to share
Thanks to cjbarth, that was helpful. I made a similar version in C # in case it helps anyone.
public class ColumnTextSimple : ColumnText
{
Document document;
Rectangle[] columns;
public ColumnTextSimple(PdfContentByte writer, Document workingDocument, int columnCount, float columnSpacing) : base(writer)
{
document = workingDocument;
CalculateColumns(columnCount, columnSpacing);
}
private void CalculateColumns(int columnCount, float columnSpacing)
{
float columnWidth;
float columnHeight;
columnWidth = ((document.PageSize.Width - document.LeftMargin - document.RightMargin) - (columnSpacing * (columnCount - 1))) / columnCount;
columnHeight = (document.PageSize.Height - document.TopMargin - document.BottomMargin);
columns = new Rectangle[columnCount];
for (int c = 0; c < columnCount; c++)
{
float llx = ((columnWidth + columnSpacing) * c) + document.LeftMargin;
float lly = document.BottomMargin;
float urx = llx + columnWidth;
float ury = columnHeight;
columns[c] = new Rectangle(llx, lly, urx, ury);
}
}
public void produceColumns()
{
int column = 0;
int status = 0;
while (ColumnText.HasMoreText(status)) // same as while(status != 1)
{
if (column >= columns.Length)
{
column = 0;
document.NewPage();
}
this.SetSimpleColumn(columns[column]);
status = this.Go();
column++;
}
}
}
I added a separate method for ProduceColumns, as this allows AddElement to be called more than once. Then you need to call Columns after all the content has been added.
source to share