介绍
我正在使用 C# 和 Spire.Xls 来编辑 excel 文件并询问 SQL 数据库。
每次运行程序 (WPF) 时,我都想打开现有的 Excel 文件,以根据 SQL 数据库信息删除和创建工作表和数据透视表。一切正常,我清空用作数据源的 2 张工作表并删除 pivot1 的工作表(数据透视表 1)并创建一个具有相同名称的新工作表并基于数据源工作表创建一个新的数据透视表(3 个数据透视表的 2 个数据源工作表表,其中 2 个共享一个数据源)。
问题
之后,我尝试对数据透视表 2 执行相同的过程,删除数据透视表并重新创建。代码一直执行到最后(删除和创建),但在我尝试保存文件后,我得到 zip 中已经存在条目 pivotCacheDefinition2.xml 并且文件已损坏。经过更多测试后,我发现即使我只删除/删除工作表 pivot2 并保存文件(不包括执行中的创建过程),它也会给我同样的错误。所以我只能删除和创建 1 个数据透视表。如何解决这个问题?
主要代码
try
{
excel_manager em = new excel_manager();
//excel_editor ee = new excel_editor();
em.loadExcelFile("C:\\test\\situatie_pivoti_27.07 - 07.00.xlsx");
em.setDebugMode(true);
em.clearData("date");
em.clearData("date2");
em.addDateHeaders();
em.fillData("date", ds.Tables["dataset1"]);
em.fillData("date2", ds.Tables["dataset2"]);
em.removeSheet("pivot1", "PivotTable1");
em.create_pivot_table_one("date", "PivotTable1");
em.removeSheet("pivot2", "PivotTable4");
//em.close_and_save();
//em.create_pivot_table_two("date", "PivotTable4");
em.close_and_save();
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.ToString());
}
removeSheet 函数
public void removeSheet(String sheetName, String pivotTableName="")
{
try
{
if (sheetName.Contains("pivot"))
{
sWB.Worksheets[sheetName].Clear();
sWB.Worksheets[sheetName].ClearData();
sWB.Worksheets[sheetName].PivotTables.Remove(pivotTableName);
}
sWB.Worksheets.Remove(sheetName);
}
catch (Exception ex)
{
Console.WriteLine("Exception: ", ex.ToString());
}
}
保存文件代码
public void close_and_save()
{
sWB.SaveToFile(fileName, ExcelVersion.Version2013);
}
创建数据透视表代码
public void create_pivot_table_two(String DataSourceSheetName, String pivotTableName)
{
try
{
//Re-create worksheet pivot2
Worksheet pivot2 = sWB.CreateEmptySheet();
pivot2.Name = "pivot2";
pivot2.AllocatedRange.AutoFitColumns();
pivot2.AllocatedRange.AutoFitRows();
changeSheet("pivot2");
//Get Datasource "data"
Worksheet datasource1 = sWB.Worksheets[DataSourceSheetName];
CellRange dataRange = datasource1.Range[datasource1.FirstRow, datasource1.FirstColumn, datasource1.LastRow - 340, datasource1.LastColumn - 1];
#region Debug_Code
//var a = dataRange.CellList;
//List<String> debug = new List<string>();
//foreach (var index in a)
//{
// debug.Add(index.DisplayedText);
//}
#endregion
//Create Pivot Table 2
//PivotCache cache = this.cache1;
PivotCache cache = sWB.PivotCaches.Add(dataRange);
PivotTable pt2 = pivot2.PivotTables.Add(pivotTableName, dataRange, cache);
#region PivotTable2 Proprieties
pt2.BuiltInStyle = PivotBuiltInStyles.PivotStyleDark3;
pt2.ShowRowStripes = true;
pt2.ShowColumnGrand = false;
pt2.ShowRowGrand = false;
pt2.Options.MergeLabels = true;
#endregion
#region PivotTable2 Row and Column Field Proprieties
//creating the rows
PivotField r1 = pt2.PivotFields["nume"] as PivotField;
r1.Axis = AxisTypes.Row;
pt2.Options.RowHeaderCaption = "Row Labels";
PivotField r2 = pt2.PivotFields["numar"] as PivotField;
r2.Axis = AxisTypes.Row;
PivotField r3 = pt2.PivotFields["dela-panala"] as PivotField;
r3.Axis = AxisTypes.Row;
//creating the columns with dates
PivotField c = pt2.PivotFields["dt"] as PivotField;
c.Axis = AxisTypes.Column;
c.NumberFormat = "dd-mmm";
c.SortType = PivotFieldSortType.Ascending;
pt2.DataFields.Add(pt2.PivotFields["ocupate"], "efectuate", SubtotalTypes.Sum);
pt2.DataFields.Add(pt2.PivotFields["total"], "maxim", SubtotalTypes.Sum);
#endregion
pivot2.SetRowHeight(1, 20);
pivot2.SetColumnWidth(1, 60);
//cache.Dispose();
}catch (Exception ex)
{
}
}
excel_manager 全类代码
class excel_manager
{
Workbook sWB;
Worksheet active_sheet;
PivotCache cache1;
String filePath;
String fileName;
String[] date_headers = new string[] {"nume","numar", "total",
"ocupate", "dt", "dela-panala"};
String[] date2_headers = new string[] { "nume", "dt", "libere", "total" };
int sheetNumber;
public excel_manager()
{
sWB = new Workbook();
filePath = "";
fileName = "";
sheetNumber = 0;
cache1 = null;
}
public void loadExcelFile(String path)
{
if (File.Exists(path))
{
try
{
this.filePath = path;
sWB.LoadFromFile(filePath);
sWB.IsHideWindow = true;
fileName = sWB.FileName;
sheetNumber = sWB.Worksheets.Count;
}
catch (Exception ex)
{
Console.WriteLine("Exception: ", ex.ToString());
}
}
else
{
Console.WriteLine("File does not exist");
}
}
public void setDebugMode(bool status)
{
sWB.IsHideWindow = !(status);
}
public void changeSheet(int index)
{
if (index > 0 && index <= sheetNumber)
{
try
{
active_sheet = sWB.Worksheets[index];
active_sheet.Activate();
}
catch (Exception ex)
{
Console.WriteLine("Exception: ", ex.ToString());
}
}
else
{
Console.WriteLine("Invalid Inex for Sheet!");
}
}
public void changeSheet(String sheetName)
{
try
{
active_sheet = sWB.Worksheets[sheetName];
active_sheet.Activate();
}
catch (Exception ex)
{
Console.WriteLine("Exception: ", ex.ToString());
}
}
internal void clearData(string sheetName)
{
CellRange cr = sWB.Worksheets[sheetName].AllocatedRange;
//Clear all objects
cr.ClearAll();
}
public void removeSheet(String sheetName, String pivotTableName="")
{
try
{
if (sheetName.Contains("pivot"))
{
sWB.Worksheets[sheetName].Clear();
sWB.Worksheets[sheetName].ClearData();
sWB.Worksheets[sheetName].PivotTables.Remove(pivotTableName);
}
sWB.Worksheets.Remove(sheetName);
}
catch (Exception ex)
{
Console.WriteLine("Exception: ", ex.ToString());
}
}
public void removeSheet(int index)
{
if (index > 0 && index <= sheetNumber)
{
try
{
sWB.Worksheets.Remove(index);
}
catch (Exception ex)
{
Console.WriteLine("Exception: ", ex.ToString());
}
}
else
{
Console.WriteLine("Invalid Inex for Sheet!");
}
}
public void addSheet(String sheetName)
{
sWB.Worksheets.Add(sheetName);
}
public void close_and_save()
{
sWB.SaveToFile(fileName, ExcelVersion.Version2013);
}
internal void addDateHeaders()
{
changeSheet("date");
CellRange range1 = active_sheet.Range[active_sheet.FirstRow, active_sheet.FirstColumn, active_sheet.FirstRow, date_headers.Length];
int c1 = 0;
foreach (var i in range1)
{
i.Text = date_headers[c1];
i.Style.Font.IsBold = true;
c1++;
}
changeSheet("date2");
CellRange range2 = active_sheet.Range[active_sheet.FirstRow, active_sheet.FirstColumn, active_sheet.FirstRow, date2_headers.Length];
int c2 = 0;
foreach (var i in range2)
{
i.Text = date2_headers[c2];
i.Style.Font.IsBold = true;
c2++;
}
}
public void fillData(String sheetName, DataTable Data)
{
changeSheet(sheetName);
active_sheet.InsertDataTable(Data, true, 1, 1);
}
public void create_pivot_table_one(String DataSourceSheetName, String pivotTableName)
{
try
{
//Re-create worksheet pivot1
Worksheet pivot1 = sWB.CreateEmptySheet();
pivot1.Name = "pivot1";
pivot1.AllocatedRange.AutoFitColumns();
pivot1.AllocatedRange.AutoFitRows();
//Get Datasource "data"
Worksheet datasource1 = sWB.Worksheets[DataSourceSheetName];
CellRange dataRange = datasource1.Range[datasource1.FirstRow, datasource1.FirstColumn, datasource1.LastRow - 340, datasource1.LastColumn - 1];
#region Debug_Code
//var a = dataRange.CellList;
//List<String> debug = new List<string>();
//foreach (var index in a)
//{
// debug.Add(index.DisplayedText);
//}
#endregion
//Create Pivot Table 1
PivotCache cache = sWB.PivotCaches.Add(dataRange);
cache1 = cache;
PivotTable pt1 = pivot1.PivotTables.Add(pivotTableName, dataRange, cache);
#region PivotTable1 Proprieties
pt1.BuiltInStyle = PivotBuiltInStyles.PivotStyleDark4;
pt1.ShowColumnGrand = false;
pt1.ShowRowGrand = false;
pt1.ShowRowStripes = true;
pt1.Options.MergeLabels = true;
#endregion
#region PivotTable1 Row and Column Field Proprieties
//creating the rows
PivotField r1 = pt1.PivotFields["nume"] as PivotField;
r1.Axis = AxisTypes.Row;
pt1.Options.RowHeaderCaption = "Row Labels";
//creating the columns with dates
PivotField c = pt1.PivotFields["dt"] as PivotField;
c.Axis = AxisTypes.Column;
c.NumberFormat = "dd-mmm";
c.SortType = PivotFieldSortType.Ascending;
pt1.DataFields.Add(pt1.PivotFields["numar"], "numar_gh", SubtotalTypes.Count); //this won't work
pt1.DataFields.Add(pt1.PivotFields["total"], "maxim", SubtotalTypes.Sum);
pt1.DataFields.Add(pt1.PivotFields["ocupate"], "efectuate", SubtotalTypes.Sum);
#endregion
pivot1.SetRowHeight(1, 20);
pivot1.SetColumnWidth(1, 60);
//cache.Dispose();
}
catch (Exception ex)
{
}
}
public void create_pivot_table_two(String DataSourceSheetName, String pivotTableName)
{
try
{
//Re-create worksheet pivot2
Worksheet pivot2 = sWB.CreateEmptySheet();
pivot2.Name = "pivot2";
pivot2.AllocatedRange.AutoFitColumns();
pivot2.AllocatedRange.AutoFitRows();
changeSheet("pivot2");
//Get Datasource "data"
Worksheet datasource1 = sWB.Worksheets[DataSourceSheetName];
CellRange dataRange = datasource1.Range[datasource1.FirstRow, datasource1.FirstColumn, datasource1.LastRow - 340, datasource1.LastColumn - 1];
#region Debug_Code
//var a = dataRange.CellList;
//List<String> debug = new List<string>();
//foreach (var index in a)
//{
// debug.Add(index.DisplayedText);
//}
#endregion
//Create Pivot Table 2
//PivotCache cache = this.cache1;
PivotCache cache = sWB.PivotCaches.Add(dataRange);
PivotTable pt2 = pivot2.PivotTables.Add(pivotTableName, dataRange, cache);
#region PivotTable2 Proprieties
pt2.BuiltInStyle = PivotBuiltInStyles.PivotStyleDark3;
pt2.ShowRowStripes = true;
pt2.ShowColumnGrand = false;
pt2.ShowRowGrand = false;
pt2.Options.MergeLabels = true;
#endregion
#region PivotTable2 Row and Column Field Proprieties
//creating the rows
PivotField r1 = pt2.PivotFields["nume"] as PivotField;
r1.Axis = AxisTypes.Row;
pt2.Options.RowHeaderCaption = "Row Labels";
PivotField r2 = pt2.PivotFields["numar"] as PivotField;
r2.Axis = AxisTypes.Row;
PivotField r3 = pt2.PivotFields["dela-panala"] as PivotField;
r3.Axis = AxisTypes.Row;
//creating the columns with dates
PivotField c = pt2.PivotFields["dt"] as PivotField;
c.Axis = AxisTypes.Column;
c.NumberFormat = "dd-mmm";
c.SortType = PivotFieldSortType.Ascending;
pt2.DataFields.Add(pt2.PivotFields["ocupate"], "efectuate", SubtotalTypes.Sum);
pt2.DataFields.Add(pt2.PivotFields["total"], "maxim", SubtotalTypes.Sum);
#endregion
pivot2.SetRowHeight(1, 20);
pivot2.SetColumnWidth(1, 60);
//cache.Dispose();
}catch (Exception ex)
{
}
}
public void update_pivot_table_one()
{
XlsPivotTable pt = sWB.Worksheets["pivot1"].PivotTables[0] as XlsPivotTable;
pt.Cache.IsRefreshOnLoad = true;
}
}
更新1
经过一整天的进一步测试,我得出结论,使用此代码运行另一个文件工作得很好,我可以创建 2 个数据透视表。
使用 7zip 打开这个文件,我们可以看到 2 个文件:
- pivotCacheDefinition1.xls
- pivotCacheDefinition2.xls
新问题 当我使用 OG 原始文件来运行程序时,在删除工作表 pivot2 并保存后会引发异常。
打开打算运行的原始文件(在异常损坏并运行代码之后)我们只观察到 1 个文件:
- pivotCacheDefinition2.xls
似乎问题与文件相关而不是与代码相关?也许吧,但我不知道为什么。
链接到调试图片和异常的帖子: imgur debug images