iTextSharp: разбиение таблицы на страницы вручную путем подсчета строк, но что, если строка переносится? - PullRequest
0 голосов
/ 17 декабря 2018

Я использую iTextSharp для создания PDF.Этот PDF-файл содержит таблицу, которую я создаю с использованием DirectContent.Я считаю строки, которые я пишу, и делаю document.NewPage(), когда количество строк достигает 45. Кажется, все работает нормально , если ни одна из строк не переносится во вторую строку.Если это произойдет, мой счетчик строк будет отключен, и в конечном итоге мой пейджинг будет неправильным.У кого-нибудь есть идеи, как я могу обойти эту проблему?Моя полная программа выглядит следующим образом:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iTextSharp.text;
using iTextSharp.text.pdf;
using static iTextSharp.text.Font;

namespace iTextSharp_long_table
{
    class Program
    {
        static void Main(string[] args)
        {
            MemoryStream stream = new MemoryStream();
            using (stream)
            using (Document document = new Document(PageSize.LETTER))
            {
                PdfWriter writer = PdfWriter.GetInstance(document, stream);
                document.Open();

                PdfPTable table = new PdfPTable(4);
                table.TotalWidth = 72 * 7.5f;
                int nrows = 0;
                int topOfPage = 0;

                Font font = new Font(FontFamily.HELVETICA, 9, Font.BOLD);
                Font fontPlain = new Font(FontFamily.HELVETICA, 9);
                for (int i = 0; i < 20 ; i++)    // jobs
                {
                    if (nrows >= 45)
                    {
                        table.WriteSelectedRows(topOfPage, -1, 36, 9 * 72, writer.DirectContent);
                        document.NewPage();
                        topOfPage = table.Size;
                        nrows = 0;
                    }
                    PdfPCell cell2 = new PdfPCell(new Phrase("Job " + (i + 1).ToString(), font));
                    cell2.Border = PdfPCell.TOP_BORDER + PdfPCell.LEFT_BORDER + PdfPCell.BOTTOM_BORDER;
                    cell2.BackgroundColor = new BaseColor(227, 235, 247);
                    cell2.Colspan = 3;
                    table.AddCell(cell2);

                    string currency = string.Format("{0:C}", Math.Round(1.23, 2));
                    cell2 = new PdfPCell(new Phrase(currency, font));
                    cell2.BackgroundColor = new BaseColor(227, 235, 247);
                    cell2.HorizontalAlignment = Element.ALIGN_RIGHT;
                    cell2.Border = PdfPCell.TOP_BORDER + PdfPCell.RIGHT_BORDER + PdfPCell.BOTTOM_BORDER;
                    table.AddCell(cell2);
                    nrows++;

                    // workitems
                    DoWorkItems(ref table, ref nrows, ref topOfPage, document, ref writer, ref fontPlain);

                    // add a blank row before the next job
                    cell2 = new PdfPCell(new Phrase(" "));
                    cell2.Colspan = 4;
                    cell2.Border = PdfPCell.NO_BORDER;
                    table.AddCell(cell2);
                    nrows++;
                }

                table.WriteSelectedRows(topOfPage, -1, 36, 9 * 72, writer.DirectContent);
                document.NewPage();
            }

            byte[] result = stream.GetBuffer();
            File.WriteAllBytes(@"c:\temp\Long Table.pdf", result);
            Process.Start(@"c:\temp\Long Table.pdf");
        }

        public static void DoWorkItems(ref PdfPTable table, ref int nrows, ref int topOfPage, 
            Document document, ref PdfWriter writer, ref Font fontPlain)
        {
            for (int j = 0; j < 5 ; j++)     // workitems
            {
                if (nrows >= 45)
                {
                    table.WriteSelectedRows(topOfPage, -1, 36, 9 * 72, writer.DirectContent);
                    document.NewPage();
                    topOfPage = table.Size;
                    nrows = 0;
                }
                string str = "     - Item " + (j + 1).ToString();
                Phrase phrase = new Phrase(str, fontPlain);
                PdfPCell cell2 = new PdfPCell(phrase);
                cell2.Colspan = 4;
                cell2.Border = PdfPCell.NO_BORDER;
                table.AddCell(cell2);
                nrows++;
            }
        }
    }
}

1 Ответ

0 голосов
/ 18 декабря 2018

Обычно лучше оставить детали макета в iText, в частности, для основного контента, который может распространяться или не распространяться по страницам.Единственный контент, который обычно требуется для создания макета, - это верхний и нижний колонтитулы, фон и аналогичные материалы.

В данном случае в комментариях выяснилось, что причиной, по которой ОП сам обрабатывал детали макета, была:

Я делаю это потому, что хочу запустить таблицу в определенной точке страницы (в настоящей программе я рисую изображение вверху страницы).

Но это также возможно, позволяя iText обрабатывать макет: нужно просто установить поля страницы так, чтобы оставшееся пространство, пространство, которое iText использует для размещения контента, было пространством, в котором нужно, чтобы его контент отображался..

(Осторожно: вы должны установить поля до создания рассматриваемой страницы. В случае первой страницы это, в частности, означает, что вы должны сделать это перед открытием документа.)

Это позволило решить проблему ОП:

Поскольку мне не нужно использовать прямой контент, я могу просто добавить таблицу в документПозвольте iTextSharp сделать нумерацию страниц.Проблема решена: -).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...