Itextsharp: настроить 2 элемента на одной странице - PullRequest
1 голос
/ 29 сентября 2011

Итак, у меня возникла эта проблема с использованием C # (.NET 4.0 + WinForms) и iTextSharp 5.1.2.

У меня есть несколько отсканированных изображений, хранящихся в БД, и мне нужно создавать на лету PDF сэти изображения.Некоторые файлы имеют только одну страницу, а другие сотни.Это прекрасно работает, используя:

    foreach (var page in pages)
    {
        Image pageImage = Image.GetInstance(page.Image);
        pageImage.ScaleToFit(document.PageSize.Width,document.PageSize.Height);
        pageImage.Alignment = Image.ALIGN_TOP | Image.ALIGN_CENTER;
        document.Add(pageImage);
        document.NewPage();
        //...
    }

Проблема в следующем:

Мне нужно добавить небольшую таблицу внизу последней страницы.

Я пытаюсь:

    foreach (var page in pages)
    {
        Image pageImage = Image.GetInstance(page.Image);
        pageImage.ScaleToFit(document.PageSize.Width,document.PageSize.Height);
        pageImage.Alignment = Image.ALIGN_TOP | Image.ALIGN_CENTER;
        document.Add(pageImage);
        document.NewPage();
        //...
    }
    Table t = new table....
    document.Add(t);

Таблица успешно добавлена, но если размер изображения соответствует размеру страницы документа, то таблица добавляется на следующей странице.

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

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

Есть идеи?

Ответы [ 2 ]

12 голосов
/ 29 сентября 2011

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

Первое, что PdfPTable имеетспециальный метод, называемый WriteSelectedRows(), который позволяет рисовать таблицу с точной x,y координатой.Он имеет шесть перегрузок, но наиболее часто используемым является, вероятно:

PdfPTable.WriteSelectedRows(int rowStart,int rowEnd, float xPos, float yPos, PdfContentByte canvas)

Чтобы разместить таблицу с верхним левым углом, расположенным на 400,400, вы должны позвонить:

t.WriteSelectedRows(0, t.Rows.Count, 400, 400, writer.DirectContent);

ПередПри вызове этого метода вы должны установить ширину таблицы, используя сначала SetTotalWidth():

//Set these to your absolute column width(s), whatever they are.
t.SetTotalWidth(new float[] { 200, 300 });

Во-вторых, высота таблицы неизвестна до тех пор, пока не будет отображена вся таблица.Это означает, что вы не можете точно знать, где разместить стол, чтобы он действительно находился внизу.Решением этой проблемы является визуализация таблицы во временный документ, а затем вычисление высоты.Ниже приведен метод, который я использую для этого:

    public static float CalculatePdfPTableHeight(PdfPTable table)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            using (Document doc = new Document(PageSize.TABLOID))
            {
                using (PdfWriter w = PdfWriter.GetInstance(doc, ms))
                {
                    doc.Open();

                    table.WriteSelectedRows(0, table.Rows.Count, 0, 0, w.DirectContent);

                    doc.Close();
                    return table.TotalHeight;
                }
            }
        }
    }

Это можно назвать так:

        PdfPTable t = new PdfPTable(2);
        //In order to use WriteSelectedRows you need to set the width of the table
        t.SetTotalWidth(new float[] { 200, 300 });
        t.AddCell("Hello");
        t.AddCell("World");
        t.AddCell("Test");
        t.AddCell("Test");

        float tableHeight = CalculatePdfPTableHeight(t);

Итак, со всем этим вот полный рабочий пример WinForms для iTextSharp 5.1.1.0 (я знаю, что вы сказали 5.1.2, но это должно работать точно так же).Этот образец ищет все файлы JPEG в папке на рабочем столе под названием «Тест».Затем он добавляет их в 8,5 "x11" PDF.Затем на последней странице PDF или, если на единственной странице есть только 1 JPEG, он увеличивает высоту PDF, увеличивая высоту таблицы, которую мы добавляем, и затем помещает таблицу внизу слева.угол.См. Комментарии в самом коде для дальнейшего объяснения.

using System;
using System.Text;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;

namespace Full_Profile1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public static float CalculatePdfPTableHeight(PdfPTable table)
        {
            //Create a temporary PDF to calculate the height
            using (MemoryStream ms = new MemoryStream())
            {
                using (Document doc = new Document(PageSize.TABLOID))
                {
                    using (PdfWriter w = PdfWriter.GetInstance(doc, ms))
                    {
                        doc.Open();

                        table.WriteSelectedRows(0, table.Rows.Count, 0, 0, w.DirectContent);

                        doc.Close();
                        return table.TotalHeight;
                    }
                }
            }
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            //Create our table
            PdfPTable t = new PdfPTable(2);
            //In order to use WriteSelectedRows you need to set the width of the table
            t.SetTotalWidth(new float[] { 200, 300 });
            t.AddCell("Hello");
            t.AddCell("World");
            t.AddCell("Test");
            t.AddCell("Test");

            //Calculate true height of the table so we can position it at the document's bottom
            float tableHeight = CalculatePdfPTableHeight(t);

            //Folder that we are working in
            string workingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test");

            //PDF that we are creating
            string outputFile = Path.Combine(workingFolder, "Output.pdf");

            //Get an array of all JPEGs in the folder
            String[] AllImages = Directory.GetFiles(workingFolder, "*.jpg", SearchOption.TopDirectoryOnly);

            //Standard iTextSharp PDF init
            using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                using (Document document = new Document(PageSize.LETTER))
                {
                    using (PdfWriter writer = PdfWriter.GetInstance(document, fs))
                    {
                        //Open our document for writing
                        document.Open();

                        //We do not want any margins in the document probably
                        document.SetMargins(0, 0, 0, 0);

                        //Declare here, init in loop below
                        iTextSharp.text.Image pageImage;

                        //Loop through each image
                        for (int i = 0; i < AllImages.Length; i++)
                        {
                            //If we only have one image or we are on the second to last one
                            if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
                            {
                                //Increase the size of the page by the height of the table
                                document.SetPageSize(new iTextSharp.text.Rectangle(0, 0, document.PageSize.Width, document.PageSize.Height + tableHeight));
                            }

                            //Add a new page to the PDF
                            document.NewPage();

                            //Create our image instance
                            pageImage = iTextSharp.text.Image.GetInstance(AllImages[i]);
                            pageImage.ScaleToFit(document.PageSize.Width, document.PageSize.Height);
                            pageImage.Alignment = iTextSharp.text.Image.ALIGN_TOP | iTextSharp.text.Image.ALIGN_CENTER;
                            document.Add(pageImage);

                            //If we only have one image or we are on the second to last one
                            if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
                            {
                                //Draw the table to the bottom left corner of the document
                                t.WriteSelectedRows(0, t.Rows.Count, 0, tableHeight, writer.DirectContent);
                            }

                        }

                        //Close document for writing
                        document.Close();
                    }
                }
            }

            this.Close();
        }
    }
}

РЕДАКТИРОВАТЬ

Ниже приведена правка на основе ваших комментариев.Я публикую только содержимое цикла for, который является единственной частью, которая изменилась.При звонке ScaleToFit нужно просто учитывать tableHeight.

                    //Loop through each image
                    for (int i = 0; i < AllImages.Length; i++)
                    {
                        //Add a new page to the PDF
                        document.NewPage();

                        //Create our image instance
                        pageImage = iTextSharp.text.Image.GetInstance(AllImages[i]);

                        //If we only have one image or we are on the second to last one
                        if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
                        {
                            //Scale based on the height of document minus the table height
                            pageImage.ScaleToFit(document.PageSize.Width, document.PageSize.Height - tableHeight);
                        }
                        else
                        {
                            //Scale normally
                            pageImage.ScaleToFit(document.PageSize.Width, document.PageSize.Height);
                        }

                        pageImage.Alignment = iTextSharp.text.Image.ALIGN_TOP | iTextSharp.text.Image.ALIGN_CENTER;
                        document.Add(pageImage);

                        //If we only have one image or we are on the second to last one
                        if ((AllImages.Length == 1) | (i == (AllImages.Length - 1)))
                        {
                            //Draw the table to the bottom left corner of the document
                            t.WriteSelectedRows(0, t.Rows.Count, 0, tableHeight, writer.DirectContent);
                        }

                    }
0 голосов
/ 07 сентября 2013

Просто используйте метод table.CalculateHeights (), если вы хотите узнать высоту таблицы.

...