itextsharp преобразует 1 столбец в 3 столбца на странице - PullRequest
1 голос
/ 15 июля 2011

Мне было интересно, смогу ли я получить какую-то помощь, конвертируя это в 3 столбца (спускаясь влево) на отчет о странице.

using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {

            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(@"c:\\temp\\column_example.pdf", FileMode.Create));
                document.Open();
                PdfContentByte cb = writer.DirectContent;

                float pos;
                PdfPTable table;
                PdfPCell cell = new PdfPCell(new Phrase(string.Empty));
                Phrase phrase;
                float columnWidth = (PageSize.LETTER.Width - 36);
                ColumnText ct = GetColumn(cb, columnWidth);

                int status = 0;


                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);
                    }

                    ct.AddElement(table);
                    pos = ct.YLine;
                    status = ct.Go(true);
                    Console.WriteLine("Lines written:" + ct.LinesWritten + " Y-position: " + pos + " - " + ct.YLine);
                    if (!ColumnText.HasMoreText(status))
                    {
                        ct.AddElement(table);
                        ct.YLine = pos;
                        ct.Go(false);
                    }
                    else
                    {
                        document.NewPage();
                        ct.SetText(null);
                        ct.AddElement(table);
                        ct.YLine = PageSize.LETTER.Height - 36;
                        ct.Go();
                    }
                }
            }

            catch (DocumentException de)
            {
                Console.Error.WriteLine(de.Message);
            }

            catch (IOException ioe)
            {
                Console.Error.WriteLine(ioe.Message);
            }
            finally
            {
                document.Close();
            }
            Console.ReadLine();
        }


        private static ColumnText GetColumn(PdfContentByte cb, float columnWidth)
        {
            var ct = new ColumnText(cb);
            ct.SetSimpleColumn(36, 36, columnWidth, PageSize.LETTER.Height - 36, 18, Element.ALIGN_JUSTIFIED);
            return ct;
        }
    }
}

Я действительно новичок в itextsharp и не могу найти хороших примеров того, как это сделать.

Спасибо за любую помощь

1 Ответ

2 голосов
/ 15 июля 2011

Самый простой способ сделать это - поместить ваши отдельные таблицы в основную таблицу из 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 - «выше», а не ниже.

...