c# - EPPLUS 使用 loadfromcollection 与合并的单元格
问题描述
我必须填写这样的excel
我在每一行上合并了单元格。我正在尝试使用 loadfromcollection,但它忽略了合并的单元格并填充了每一行。
请问您知道有什么快速的方法吗?
编辑:我认为一种方法是实现自定义 loadfromcollection 步骤如下:
- 迭代集合
- 对于每个对象,使用反射读取属性/字段
- 迭代每一行的单元格
- 检查范围地址是否在 worksheet.mergecells
- 用属性/字段值填充它
但是在复杂的工作表(带有一些 loadfromcollection)的情况下,我认为这种方法可能很繁重且成本很高。
编辑2:添加一个例子:这样的代码
public class MyObj
{
public string first {get; set;}
public string second {get; set;}
}
...
List<MyObj> myList = new List<MyObj>() {
new MyObj() {first = "first1", second = "second1"},
new MyObj() {first = "first2", second = "second2"} };
...
ws.Cells["A1"].LoadFromCollection(myList);
在普通工作表中,loadfromcollection 具有以下输出:
如果我在填充后合并 A 列和 B 列,我会得到:
如果我的工作表模板是
然后我尝试使用 loadfromcollection 填充它我得到了这个结果
loadfromcollection 忽略合并的单元格,并填充 A 和 B 列,但我的期望是
解决方案
问题是这是 excel 中的“有意”行为。当您在 A 列和 B 列中有值并将它们合并时,将仅保留 A 列中的值。LoadFromCollection 没有这种场景的重载。
我可以想到几种可行的“解决方法”,具体取决于您希望代码的通用程度。
- 您使用反射遍历对象属性的解决方案将起作用。如果“合并”总是两列,我建议使用列计数器并在每次属性迭代时添加 2。
所以像这样(当然你已经定义了 excel 包和工作表等以及起始行和列):
var type = testObject.GetType();
var properties = type.GetProperties();
foreach (var property in properties)
{
cell = worksheet.Cells[row, column];
cell.Value = property.GetValue(testObject);
column += 2;
}
- 或者,您可以决定从模板中删除合并并将其移动到您的代码中。这也可以提供更多的一致性和灵活性。
上面的代码看起来更像:
var type = testObject.GetType();
var properties = type.GetProperties();
foreach (var property in properties)
{
cellRange = worksheet.Cells[row, column, row, column + 1];
cellRange.Merge = true;
cellRange.Value = property.GetValue(testObject);
column += 2;
}
您甚至可以有点“疯狂”并根据属性使范围变量。您使用所有已知属性创建一个 switch 语句,这些属性应该是 2 个合并单元格,那些应该是 3 个合并单元格等。然后设置默认的 1 个单元格/列。通过这种方式,您可以获得对输出的完全控制,并且将来更容易调整。
编辑
我的情况有点复杂,不是我所有的合并单元格都由 2 个单元格组成
一些代码用一些代码来说明我的上述陈述,以帮助解决这个问题。使用旧的 switch 表示法,因为你说它是一个“旧项目”,我假设你还没有使用 C# 8 或更高版本。
var type = testObject.GetType();
var properties = type.GetProperties();
int columnMergeSize;
foreach (var property in properties)
{
columnMergeSize = GetPropertyColumnMergeSize(property.Name);
cellRange = worksheet.Cells[row, column, row, column + columnMergeSize];
cellRange.Merge = true;
cellRange.Value = property.GetValue(testObject);
column += 2;
}
private int GetPropertyColumnMergeSize(string propertyName)
{
switch (propertyName)
{
case "Property1":
case "Property2":
case "Property3":
case "Property4":
return 2;
case "Property5":
case "Property6":
return 3;
default:
return 1;
}
}
这将比每次都读取单元格的属性以查看它是否“合并”要少。我还发现,如果您从 excel 模板中删除几乎所有格式,它的加载速度会更快,从而加快您的程序。
您可以决定将其放入服务中,然后将方法注入 DI 需要的任何地方,或者您可以将其设为静态方法并使用它。
推荐阅读
- automata - 找到一个集合以显示与非常规语言的可区分性
- javascript - 如何在 Node.js 中使用 Async Await
- php - 使用 PHP 将 6 个数组字节转换为 int64
- flutter - 参数 'id' 的值不能为 'null',因为它的类型,但隐含的默认值是 'null'
- php - 自动递增值作为输入分配,然后使用值从数据库中删除项目;
- python - selenium.common.exceptions.InvalidArgumentException:
- web-scraping - 谷歌表格网页抓取,importxml失败
- django - 如何在序列化程序中过滤 ManyToManyField
- python - 正则表达式帮助 - python
- c++ - 使用 i686-w64-mingw32-g++ 编译 Chaiscript 失败