开发者

itextsharp nextcolumn not working

I'm trying to set up a simple 2 column page, write to the first column, then the second. However the code below places both paragraphs in the second column. The current column trace appears to be correct (first 开发者_如何学Go0, then 1)

Any ideas what I'm 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


I couldn't get NextColumn() to work wih a MultiColumnText object and I couldn't find any samples (in .NET) that do.

A MultiColumnText makes creating columns in a document relatively easy but in exchange you give up a lot control over layout. You can use the ColumnText object which gives you a great deal of control over column layout but requires more code.

Here's a simple but complete example of what you're 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 won't even serve as a starting point for you in what you're 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


As I found that the latest versions of iTextSharp don't include the MultiColumnText class I created one of my own of sorts.

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 could easily be expanded to Shadow the other functions in ColumnText.


Thanks cjbarth, this was useful. I have done a similar version in C# if this 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 have added a separate method for ProduceColumns as this allows AddElement to be called more than once. ProduceColumns must then be called once all content has been added.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜