Самый простой способ сделать это - поместить ваши отдельные таблицы в основную таблицу из 3 столбцов. Ниже приведен код, который делает это. Возможно, вы захотите настроить поля, ширину и границы, но это должно как минимум начать.
Кроме того, так как вы сказали, что вы новичок в iTextSharp, я собираюсь предположить, что у вас нет особой необходимости использовать DirectContent
. DC очень мощный, но большую часть того, что вам нужно сделать с iTextSharp, вы можете вместо этого делать через определенные объекты. Приведенный ниже код удаляет все данные DC.
//(iText 5.1.1.0)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "column_example.pdf");
Console.WriteLine("-> Creates a PDF file with a block of Text.");
Document document = new Document(PageSize.LETTER);
try
{
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(filePath, FileMode.Create));
document.Open();
//Create a master table with 3 columns
PdfPTable masterTable = new PdfPTable(3);
//Set the column widths, this should probably be adjusted
masterTable.SetWidths(new float[] { 200, 200, 200 });
PdfPTable table;
PdfPCell cell;
Phrase phrase;
string line = "Line{0}";
for (int i = 0; i < 50; i++)
{
table = new PdfPTable(1);
table.SpacingAfter = 9F;
cell = new PdfPCell(new Phrase("Header for table " + i));
table.AddCell(cell);
for (int j = 0; j < (i % 2 == 0 ? 5 : 7); j++)
{
phrase = new Phrase(string.Format(line, i));
cell = new PdfPCell(phrase);
table.AddCell(cell);
}
//Add the sub-table to our master table instead of the writer
masterTable.AddCell(table);
}
//Add the master table to our document
document.Add(masterTable);
}
catch (DocumentException de)
{
Console.Error.WriteLine(de.Message);
}
catch (IOException ioe)
{
Console.Error.WriteLine(ioe.Message);
}
finally
{
document.Close();
}
Console.ReadLine();
}
}
}
EDIT
Извините, я не понял из вашего исходного поста, что вы искали, но сделайте сейчас. К сожалению, вы входите в сферу Math и Mod. Мне не нужно время (или умственные способности этим утром), чтобы пройти через это полностью, но, надеюсь, я смогу дать вам старт.
Весь мир программирования основан на слева направо и , а затем сверху вниз, когда вы переключаете его, вам, как правило, приходится прыгать через гигантские обручи, чтобы делать то, что вы хотите (например, создание списка HTML из 3 столбцов, алфавитно расположенных с буквами A в столбце 1, буквами B в столбце 2 и т. д.)
Чтобы сделать то, что вы хотите, вам нужно знать высоту таблиц, чтобы вы могли рассчитать, сколько по вертикали вы можете получить на странице. К сожалению, высота таблицы не известна до времени рендеринга. Решение (по крайней мере для меня) состоит в том, чтобы нарисовать каждую таблицу во временный документ, который позволяет нам знать высоту, затем мы сохраняем таблицу в массиве и выбрасываем документ. Теперь у нас есть массив таблиц с известной высотой, через которые мы можем пройти.
Фрагмент ниже делает все это. Я изменил правило подсчета строк на случайное число от 2 до 9, чтобы получить больше разнообразия в данных выборки. Кроме того, начиная с iTextSharp 5.1 (я думаю, что это правильная версия), многие из «больших» объектов поддерживают IDisposable
, поэтому я using
. Если вы используете более старую версию, вам нужно удалить using
и переключиться на обычное объявление переменной. Надеюсь, комментарии имеют смысл. Вы увидите, что я вытащил некоторые магические числа в переменные тоже.
//Our array of tables
List<PdfPTable> Tables = new List<PdfPTable>();
//Create a random number of rows to get better sample data
int rowCount;
Random r = new Random();
string line = "Line {0}";
PdfPTable table;
//This is the horizontal padding between tables
float hSpace = 5;
//Total number of columns that we want
int columnCount = 3;
//Create a temporary document to write our table to so that their sizes can be calculated
using (Document tempDoc = new Document(PageSize.LETTER))
{
using (MemoryStream tempMS = new MemoryStream())
{
using (PdfWriter tempW = PdfWriter.GetInstance(tempDoc, tempMS))
{
tempDoc.Open();
//Calculate the table width which is the usable space minus the padding between tables divided by the column count
float documentUseableWidth = tempDoc.PageSize.Width - tempDoc.LeftMargin - tempDoc.RightMargin;
float totalTableHPadding = (hSpace * (columnCount - 1));
float tableWidth = (documentUseableWidth - totalTableHPadding) / columnCount;
for (int i = 0; i < 50; i++)
{
table = new PdfPTable(1);
table.AddCell(new PdfPCell(new Phrase("Header for table " + i)));
rowCount = r.Next(2, 10);
for (int j = 0; j < rowCount; j++)
{
table.AddCell(new PdfPCell(new Phrase(string.Format(line, i))));
}
//In order to use WriteSelectedRows you need to set the width of the table
table.SetTotalWidth(new float[] { tableWidth });
//Write the table to our temporary document in order to calculate the height
table.WriteSelectedRows(1, table.Rows.Count, 0, 0, tempW.DirectContent);
//Add the table to our array
Tables.Add(table);
}
tempDoc.Close();
}
}
}
Получив массив таблиц, вы можете просмотреть их и нарисовать, используя:
Tables[i].WriteSelectedRows(1, Tables[i].Rows.Count, curX, curY, writer.DirectContent);
Где i
- ваш текущий индекс таблицы, а curX
и curY
- ваши текущие координаты.
Надеюсь, это заставит вас двигаться в правильном направлении. WriteSelectedRows
отлично ставит стол точно там, где вы хотите.
И последнее, что нужно запомнить, координата Y
, которую он принимает, начинается в нижней части документа, а не в верхней части, поэтому 0 - это нижняя часть, а 720 - «выше», а не ниже.