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

+1


source to share


3 answers


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

+2


source


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

.

+1


source


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.

0


source







All Articles