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.
精彩评论