Excel表验证/公式未复制到新表行

时间:2014-08-04 09:52:03

标签: c# excel openxml openxml-sdk epplus

我目前正在使用EPPlus库将大量数据导出到每个工作表的几个工作表和表格中。

我已经能够创建列表验证,并通过名为range的查找工作表完美地工作。但是,我遇到了一些我无法弄清楚的奇怪行为。

开始:

我下载了这个文件。我打开文件。我选择带有表格的电子表格,表格中有多行,还有一个列表验证列,其中选项是/否可从下拉列表中选择。每行都有此列表验证。

情景1:

然后,我在excel表中创建一个新行,方法是从excel表的右下角拖动以创建新行。公式未复制到新行。我现在已经在excel表中丢失了对新行的验证。

情景2:

我删除了excel表中的所有现有行,但第一行(在Yes / No列中仍包含列表验证)除外。我那么在excel表中创建一个新行,方法是从excel表的右下角拖动以创建新行。

将公式IS复制到新行,我现在可以使用提供的验证将新的有效数据插入此行。

我的代码的逻辑:

每个单元格都通过循环对其进行验证,该循环获得单元格需要的验证类型(即数字,日期,列表,大于,小于等)。通过命名表查找地址访问列表验证。没有XML输出错误,文件打开正常,我可以从单元格访问列表验证没有任何问题。

我试图解决这个问题的事情:

1)填充单元格区域,然后从此范围创建excel表格。 - 这背后的想法是,首先选择创建的数据,然后选择范围并将其转换为excel表。默认行为是表格中的新行只是从上面的行复制公式。所以这个解决方案看似合乎逻辑。

2)在一系列非填充单元格上创建一个excel表,然后填充此范围。 - 这背后的想法是,EPPlus在工作表中创建表的方式可能有一个错误,或者可能存在XML元素顺序的问题,而且实际上只是一个实验性的改变。

代码:

   var strategy = Strategy.CreateTableFirst;
   ExcelRange subRowDataRange = null;
   ExcelTable table = null;

   if (strategy == Strategy.CreateTableFirst)
   {
       subRowDataRange = worksheet.Cells[headerRowIndex, worksheet.Dimension.Start.Column, ToRow: headerRowIndex + groupedRowData.Count(), ToCol: dataFields.Count()];
       table = worksheet.Tables.Add(subRowDataRange, Name: null); // Auto generate Excel table name
       table.TableStyle = TableStyles.Light13;  
   }

   foreach (var field in dataFields)
   {
       // Headers
       if (strategy == Strategy.CreateTableFirst)
       {
           table.Columns[dataFields.IndexOf(field)].Name = field.Name;  
       }
       else
       {
           worksheet.Cells[headerRowIndex, columnIndex].Value = field.Name;    
       }

       // Help Text
       if (field.HelpText.HasValue())
       {
           worksheet.Cells[headerRowIndex, columnIndex].AddComment(field.HelpText, Author: "System");
       }

       int dataRowIndex = headerRowIndex + 1; // First row in the datatable

       if (groupedRowData.None())
       {
           worksheet.Cells[dataRowIndex, columnIndex].Set(field, owner: owner, rowIndex: null, addValidation: true);
       }

       // Add SubRows
       foreach (var rowData in groupedRowData)
       {
           worksheet.Cells[dataRowIndex, columnIndex].Set(field, owner: owner, rowIndex: rowData.Key, addValidation: true);
           dataRowIndex++;
       }

       columnIndex++;
   }

   if (strategy == Strategy.CreateTableLast)
   {
       subRowDataRange = worksheet.Cells[headerRowIndex, worksheet.Dimension.Start.Column, ToRow: worksheet.Dimension.End.Row + 1, ToCol: dataFields.Count()];
       table = worksheet.Tables.Add(subRowDataRange, Name: null);
       table.TableStyle = TableStyles.Light13;  
   }

}

这是代码后的excel中的输出表:

Excel Table with Data exported to excel

有趣的是,如果我手动创建表并将第一行设置为数据,则将单元格验证向下复制到下一行,然后向下拖动以创建新行并将其复制为精细。我不确定如何能够导出多行数据,并确保当用户插入新行时,会复制验证。

我下载了Microsoft XML SDK,用于将excel表与1行(我可以向下拖动以创建带有复制公式的第二行)和excel表中包含许多行的原始下载excel文件进​​行比较。 / p>

结果几乎与XML输出中的excel表相同。

Excel Table Comparison XML

删除行并保存文件以进行比较后,似乎没有任何不合适的地方。

Exported on the right, deleted rows and saved on the left

任何EPPlus大师都有想法吗?

更新:2015年4月30日。客户理解该问题并接受它是什么。没有找到解决方案。

1 个答案:

答案 0 :(得分:0)

我不熟悉EPPlus,但之前我在VBA中遇到过这个问题,并且能够通过使用看起来像这样的VBA脚本强制表填充:

LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Range(Cells(TopRowOfTable,ColumnOfTableRow1),Cells(LastRow,ColumnOfTableRow1).Filldown

基本上只是找到最后一行,然后使用filldown命令强制填充字段。