如何垂直添加单元格

时间:2014-07-30 02:49:29

标签: c# itextsharp

这里我们有一个要求。在表格中,我们需要垂直添加单元格。例如,表格可能是这样的。

Name Age   Name Age

Jim  11    Lily 9

Lucy 8     Tom  6

Lile 12

Leo  13

首先,它会在第一列中添加单元格,当第一列填满时,它会在第二列中添加单元格。所有数据都来自字典。

是否有一种垂直添加细胞的简单方法?否则,我必须水平添加单元格, 但是按计算顺序从字典中获取数据以实现这一目标。

2 个答案:

答案 0 :(得分:1)

您正在寻找的是ColumnText课程。

iText网站上提供many examples,例如this one

这些示例都是Java,但C#的“翻译”应该很简单。

答案 1 :(得分:1)

我只想详细说明@ Alexis-Pigeon的答案,其中包含一些特定于C#的代码。 (另外,iText的{C#端口appears to be missing ColumnText.START_COLUMN常量应该设置为零。)

下面的代码将文本从上到下排列成多列,然后从左到右(而不是从左到右,从上到下的普通表格)。它不是对表格的维度进行硬编码,而是根据文档的边距以及所需的列数和列之间的排水沟来计算表格的位置。可以通过将columnCountgutterWidth属性更改为顶部来更改后两者。

非常重要的是,不会从左到右从上到下创建表格单元格,以便所有内容都完美排列。相反,这将绘制任意文本,当它无法适应底部时,它将在下一列中重新开始。这可能发生在段落的中间。下面的代码发生以完美排列,但这是因为文本是受控制的。如果您将gutter50更改为20,您就会看到它如何分解。

有关具体细节,请参阅代码注释。

using (var fs = new FileStream(testFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    using (var doc = new Document()) {
        using (var writer = PdfWriter.GetInstance(doc, fs)) {
            doc.Open();

            //Number of columns to create
            var columnCount = 4;

            //Distance be columns
            var gutterWidth = 20;

            //Setup and calculate some helper variables

            //The left-most edge
            var tableLeft = doc.LeftMargin;

            //The bottom-most edge
            var tableBottom = doc.BottomMargin;

            //The available width and height of the table taking into account the document's margins
            var tableWidth = doc.PageSize.Width - (doc.LeftMargin + doc.RightMargin);
            var tableHeight = doc.PageSize.Height - (doc.TopMargin + doc.BottomMargin);

            //The width of a column taking into account the gutters (three columns have two gutters total)
            var columnWidth = (tableWidth - (gutterWidth * (columnCount - 1))) / columnCount;

            //Create an array of columns
            var columns = new List<iTextSharp.text.Rectangle>();

            //Create one rectangle per column
            for (var i = 0; i < columnCount; i++) {
                columns.Add(new iTextSharp.text.Rectangle(
                        tableLeft + (columnWidth * i) + (gutterWidth * i),               //Left
                        tableBottom,                                                     //Bottom
                        tableLeft + (columnWidth * i) + (gutterWidth * i) + columnWidth, //Right
                        tableBottom + tableHeight                                        //Top
                        )
                   );
            }

            //Create our column text object
            var ct = new ColumnText(writer.DirectContent);

            //Create and set some placeholder copy
            for (var i = 0; i < 100; i++) {
                ct.AddText(new Phrase(String.Format("This is cell {0}. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris lorem tortor, condimentum non urna congue, tincidunt viverra elit.", i)));
                //Optional but helps to add spacing
                ct.AddText(Chunk.NEWLINE);
                ct.AddText(Chunk.NEWLINE);
            }

            //As we draw content below we'll loop through each column defined above
            //This holds the current column index that we'll change in the loop
            var currentColumnIndex = 0;

            //Current status as returned from ct.go()
            int status = 0; //START_COLUMN is defined in Java but is currently missing in .Net

            //Loop until we've drawn everything
            while (ColumnText.HasMoreText(status)) {

                //Setup our column
                ct.SetSimpleColumn(columns[currentColumnIndex]);

                //To be honest, not quite sure how this is used but I think it is related to leading
                ct.YLine = columns[currentColumnIndex].Top;

                //This actually "draws" the text and will return either 0, NO_MORE_TEXT (1) or NO_MORE_COLUMN(2)
                status = ct.Go();

                //Increment our current column index
                currentColumnIndex += 1;

                //If we're out of columns
                if (currentColumnIndex > (columns.Count - 1)) {

                    //Create a new page and reset to the first column
                    doc.NewPage();
                    currentColumnIndex = 0;
                }
            }

            doc.Close();
        }
    }
}