我正在生成带有一组数据的Excel工作表,其中包括必须应用于列的公式。
例如:
C2= (B2-A2)/A2, C3= (B3-A3)/A3, C101 = (B101-A101)/A101
当我引用列R(id = 18)时,这些公式可以正常工作并且excel可以正确生成,而不会发生任何错误,但是当将其更改为id = 399的列时,excel会损坏。
这是我的带有数据的xml代码。这里的ColumnId
指出了哪一列,FieldCode
指出了该列的主题,FieldCalculation
指出了该列的公式。
<Header>
<RowId>1</RowId>
<HeaderCells>
<HeaderCell>
<ColumnId>2</ColumnId>
<FieldCode>ST1001</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>1</ColumnId>
<FieldCode>ST1000</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>3</ColumnId>
<FieldCode>ST1002</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>4</ColumnId>
<FieldCode>ST1003</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>5</ColumnId>
<FieldCode>ST1004</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>6</ColumnId>
<FieldCode>ST1005</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>7</ColumnId>
<FieldCode>ST1006</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>8</ColumnId>
<FieldCode>ST1007</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>9</ColumnId>
<FieldCode>ST1008</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>10</ColumnId>
<FieldCode>ST1009</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>11</ColumnId>
<FieldCode>ST1010</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>12</ColumnId>
<FieldCode>ST1011</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>13</ColumnId>
<FieldCode>ST1012</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>14</ColumnId>
<FieldCode>ST1013</FieldCode>
<FieldCalculation>UPPER(TRIM(CONCATENATE('ST1004', 'ST1005', 'ST1006', 'ST1007, 'ST1008', 'ST1009', 'ST1010', 'ST1011', 'ST1012')))</FieldCalculation>
</HeaderCell>
<HeaderCell>
<ColumnId>15</ColumnId>
<FieldCode>ST1030</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>400</ColumnId>
<FieldCode>ST1041</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>401</ColumnId>
<FieldCode>ST1043</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>399</ColumnId>
<FieldCode>ST1045</FieldCode>
<FieldCalculation>(ST1043-ST1041)/ST1041</FieldCalculation>
</HeaderCell>
<HeaderCell>
<ColumnId>19</ColumnId>
<FieldCode>ST1073</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>20</ColumnId>
<FieldCode>ST1074</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>21</ColumnId>
<FieldCode>ST1075</FieldCode>
</HeaderCell>
<HeaderCell>
<ColumnId>22</ColumnId>
<FieldCode>ST1076</FieldCode>
<FieldCalculation>ST1073+ST1074+ST1075</FieldCalculation>
</HeaderCell>
</HeaderCells>
</Header>
这是将字段计算转换为Formular1c1的代码,用列的绝对位置替换标题主题。
例如:
1)UPPER(TRIM(CONCATENATE('ST1004', 'ST1005', 'ST1006', 'ST1007, 'ST1008', 'ST1009', 'ST1010', 'ST1011', 'ST1012')))
转换为UPPER(TRIM(CONCATENATE(RC[-9],RC[-8],RC[-7],RC[-6],RC[-5],RC[-4],RC[-3],RC[-2],RC[-1])))
2)(ST1043-ST1041)/ST1041
转换为(RC[2]-RC[1])/RC[1]
3)ST1073+ST1074+ST1075
转换为RC[-3]+RC[-2]+RC[-1]
代码:
/// <summary>
/// Get the formula for the field
/// </summary>
/// <param name="formulaString">The formula string with header topics</param>
/// <param name="headercells">The header cells list in the excel</param>
/// <param name="columnId">The current column id</param>
/// <returns></returns>
public static string GetFieldFormula(string fieldCalculation, List<HeaderCell> headercells, int columnId)
{
string[] multiArray = fieldCalculation.Split(new Char[]
{ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')','-', '_', '=', '+', '{', '}', '[', ']', ';', ':', '"', '<', '>', '?', ',', '.', '/', '~', '`', '\\', '|'});
foreach (string column in multiArray)
{
string columnname = column.Replace("'", "").Trim();
int? machingcellId = headercells.Find(headcell => headcell.FieldCode == columnname)?.ColumnId;
if (machingcellId > 0)
{
string matchingcellname = "RC[" + (machingcellId - columnId) + "]";
fieldCalculation= Regex.Replace(fieldCalculation, column, matchingcellname);
}
}
return fieldCalculation;
}
然后按如下所示将此字段公式应用于整个列。
此处i
是当前列ID,headerCells
对象包含反序列化的xml数据。
fieldCalculation = if (!string.IsNullOrWhiteSpace(fieldCalculation))
{
string formulaString = null;
formulaString = GetFieldFormula(fieldCalculation, headerCells, i);
sheet.Cells[2, i, rowcount - 2, i].FormulaR1C1 = formulaString;
}
In this example when I change ST1045 (id =399) column's id to 18, the excel is not corrupted. If I apply only one formula at a time out of these three formula, then also the excel is not corrupted. I cant find what is the exact reason for this issue. I have used the latest version of EPPlus 4.5.3.1. Please give your suggestions.
答案 0 :(得分:0)
我可以通过更改excel版本或限制应用公式的行数来解决此问题。
ASFAIU,此问题是由于打开从EPPlus库创建的excel文件时消耗的内存。
我最初使用的是excel 2007,当我更改为excel 2016时,文件未损坏。
由于我要构建的应用程序应支持excel 2010,因此我对应用公式的行数进行了限制。如果不是,则将公式应用于列中的所有行。然后问题也得到解决。
答案 1 :(得分:0)
我用这个:
ws.Cells[row,column+1].Formula = Regex.Replace(ws.Cells[row,column].Formula, @"[A-Z]+(?=\d)+", ExcelCellAddress.GetColumnLetter(column+1));
通过正则表达式更改列的字母,这会验证在公式[A-Z]+(?=\d)+;
中搜索单元格的字母和数字