如何垂直添加单元格
本文关键字:添加 单元格 垂直 何垂直 | 更新日期: 2023-09-27 18:15:46
这里我们有一个需求。在表格中,我们需要垂直地添加单元格。例如,一个表可能是这样的:
Name Age Name Age
Jim 11 Lily 9
Lucy 8 Tom 6
Lile 12
Leo 13
首先,它将添加第一列中的单元格,当第一列已满时,它将添加第二列中的单元格。所有的数据都来自字典。
是否有一个简单的方法来添加单元格垂直?否则,我必须水平添加单元格,而从字典中获取数据则是按照计算顺序来实现的。
您要查找的是ColumnText类。
在iText网站上有很多例子,例如这个。
这些例子是用Java写的,但是"翻译"到c#应该很简单。
我只是想用一些特定于c#的代码来详细说明@Alexis-Pigeon的回答。(另外,c#版本的ittext似乎缺少ColumnText.START_COLUMN
常量,该常量应该设置为零。)
下面的代码将文本从上到下,然后从左到右(而不是普通的表格从左到右,从上到下)放置到多个列中。它没有硬编码表的尺寸,而是根据文档的页边距、需要多少列以及列之间的行距来计算表的位置。后两者可以通过向上改变columnCount
和gutterWidth
的性质来改变。
非常重要的是,这个将不会创建表格单元格从上到下,从左到右,以便所有内容完美排列。相反,这将绘制任意文本,当底部无法容纳它时,它将在下一列重新开始。这可能发生在段落中间。下面的代码恰好对齐得很好,但这是因为文本受到了控制。如果你把gutter
从50
改为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();
}
}
}