我目前正在使用EPPlus项目来操作某些.xlsx文件。基本思想是我必须从给定的模板创建一个新文件。
但是当我从模板创建新文件时,表中的所有计算列都搞乱了。
我使用的代码如下:
static void Main(string[] args)
{
const string templatePath = "template_worksheet.xlsx"; // the path of the template
const string resultPath = "result.xlsx"; // the path of our result
using (var pck = new ExcelPackage(new FileInfo(resultPath), new FileInfo(templatePath))) // creating a package with the given template, and our result as the new stream
{
// note that I am not doing any work ...
pck.Save(); // savin our work
}
}
例如,对于.xlsx文件(具有3列的表,最后一个只是其他列的总和),程序会创建一个.xlsx文件,其中最后一列具有相同的值(仅限正确)对于所有行中的第一行。
以下图片显示了结果:
现在的问题是: 这里发生了什么 ?我的代码错了吗? 如果没有出现意外行为,我怎样才能完成这项任务?
答案 0 :(得分:1)
那绝对是对那里的东西。我自己能够重现它。它与您创建的表有关。如果您打开文件并使用"转换为范围"将其删除; “表格工具”选项卡中的选项可以解决问题。
我查看了源代码,它在zip级别提取了xml文件,并没有看到任何迹象表明它实际上正在弄乱它们 - 似乎是一个直接的副本。
非常奇怪,因为如果我们创建并保存包含来自EPPlus的表的xlsx文件,问题就不存在了。这很好用:
[TestMethod]
public void Template_Copy_Test()
{
//http://stackoverflow.com/questions/28722945/epplus-with-a-template-is-not-working-as-expected
const string templatePath = "c:\\temp\\testtemplate.xlsx"; // the path of the template
const string resultPath = "c:\\temp\\result.xlsx"; // the path of our result
//Throw in some data
var dtdata = new DataTable("tblData");
dtdata.Columns.Add(new DataColumn("Col1", typeof(string)));
dtdata.Columns.Add(new DataColumn("Col2", typeof(int)));
dtdata.Columns.Add(new DataColumn("Col3", typeof(int)));
for (var i = 0; i < 20; i++)
{
var row = dtdata.NewRow();
row["Col1"] = "String Data " + i;
row["Col2"] = i * 10;
row["Col3"] = i * 100;
dtdata.Rows.Add(row);
}
var templateFile = new FileInfo(templatePath);
if (templateFile.Exists)
templateFile.Delete();
using (var pck = new ExcelPackage(templateFile))
{
var ws = pck.Workbook.Worksheets.Add("Data");
ws.Cells["A1"].LoadFromDataTable(dtdata, true);
for (var i = 2; i <= dtdata.Rows.Count + 1; i++)
ws.Cells[i, 4].Formula = String.Format("{0}*{1}", ExcelCellBase.GetAddress(i, 2), ExcelCellBase.GetAddress(i, 3));
ws.Tables.Add(ws.Cells[1, 1, dtdata.Rows.Count + 1, 4], "TestTable");
pck.Save();
}
using (var pck = new ExcelPackage(new FileInfo(resultPath), templateFile)) // creating a package with the given template, and our result as the new stream
{
// note that I am not doing any work ...
pck.Save(); // savin our work
}
}
<强> BUT 强> .....
如果我们打开testtemplate.xlsx
,请删除该表,保存/关闭文件,重新打开,然后重新插入运行此问题时显示的完全相同的表:
[TestMethod]
public void Template_Copy_Test2()
{
//http://stackoverflow.com/questions/28722945/epplus-with-a-template-is-not-working-as-expected
const string templatePath = "c:\\temp\\testtemplate.xlsx"; // the path of the template
const string resultPath = "c:\\temp\\result.xlsx"; // the path of our result
var templateFile = new FileInfo(templatePath);
using (var pck = new ExcelPackage(new FileInfo(resultPath), templateFile)) // creating a package with the given template, and our result as the new stream
{
// note that I am not doing any work ...
pck.Save(); // savin our work
}
}
它必须是拉链复制方法中的东西,但我什么都没有跳出来。
但至少你可以看到解决它的问题。
欧尼
答案 1 :(得分:0)
尝试使用以下代码。此代码采用格式化和其他规则,并将它们作为xml节点添加到另一个文件。 Ernie在这里描述得非常好Importing excel file with all the conditional formatting rules to epplus解决方案的最佳部分是您还可以导入格式以及其他规则。它应该让你接近你需要的东西。
//File with your rules, can be your template
var existingFile = new FileInfo(@"c:\temp\temp.xlsx");
//Other file where you want the rules
var existingFile2 = new FileInfo(@"c:\temp\temp2.xlsx");
using (var package = new ExcelPackage(existingFile))
using (var package2 = new ExcelPackage(existingFile2))
{
//Make sure there are document element for the source
var worksheet = package.Workbook.Worksheets.First();
var xdoc = worksheet.WorksheetXml;
if (xdoc.DocumentElement == null)
return;
//Make sure there are document element for the destination
var worksheet2 = package2.Workbook.Worksheets.First();
var xdoc2 = worksheet2.WorksheetXml;
if (xdoc2.DocumentElement == null)
return;
//get the extension list node 'extLst' from the ws with the formatting
var extensionlistnode = xdoc
.DocumentElement
.GetElementsByTagName("extLst")[0];
//Create the import node and append it to the end of the xml document
var newnode = xdoc2.ImportNode(extensionlistnode, true);
xdoc2.LastChild.AppendChild(newnode);
package2.Save();
}
}
答案 2 :(得分:0)
试试这个
var package = new ExcelPackage(excelFile)
var excelSheet = package.Workbook.Worksheets[1];
for (var i = 1; i < 5; i++){
excelWorkSheet.InsertRow(i, 1, 1); // Use value of i or whatever is suitable for you
}
package.Workbook.Calculate();
如果最后一个prm设置为1
,则插入新行复制前一行格式及其公式