SpreadsheetLight 处理多个工作表
SpreadsheetLight working with multiple worksheets
我正在使用 SpreadsheetLight 从 WinForms 项目写入日志文件。我的意图是将日志条目写入同一文件中的三个工作 sheet,如果可以避免,我真的想避免使用 Interop
。
我从 Excel 中制作的模板文件开始,其中包含三个作品 sheet 和 pre-populated 的行标题,并且由于每个作品 sheet 具有相同的基本属性(可以独立变化),我将每个 sheet 封装在一个 class 中,其基础如下所示:
/// <summary>
/// Encapsulate the info we need to know about each worksheet in order to populate properly
/// </summary>
public class LogSheet
{
public SLDocument data;
public SLWorksheetStatistics stats;
public int RowCount;
public int ColumnCount;
public int currentColumn; //indicates what column you want to be writing to
public List<string> rowNames = new List<string>(); //used to make sure you're writing new data to the right row
public List<string> columnNames = new List<string>(); //used by GetLatestRun() to check if data already exists for a given serial number
public LogSheet(string sheet)
{
this.data = new SLDocument(_path, sheet);
this.stats = this.data.GetWorksheetStatistics();
this.RowCount = this.stats.EndRowIndex;
this.ColumnCount = this.stats.EndColumnIndex;
currentColumn = GetLatestRun();
for (int i = 1; i < RowCount + 1; i++)
{
this.rowNames.Add(this.data.GetCellValueAsString(i, 1));
}
for (int i = 1; i < ColumnCount + 1; i++)
{
this.columnNames.Add(this.data.GetCellValueAsString(1, i));
}
}
}
还有一些 LogSheet
class 中未显示的方法,用于将数据写入正确的位置。
这一切似乎工作正常,在调试时,我可以看到用 new LogSheet(<sheetName>)
实例化的三个工作 sheet 中的每一个都包含我编写后它们应该包含的数据给他们的东西。
问题是,当我想保存数据时,我可以逃脱this.data.Save()
,但它只保存了一个工作sheet,另外两个现在被搁置了,因为Save()
方法是终端并关闭 Excel 文件。在其他两个 sheet 中的任何一个上尝试 Save()
方法都以异常 "Object reference not set to an object"
结束,因为当然,Save()
杀死了我的传播 sheet,并且sheet 不再有任何参考。生成的文件只有我第一次保存时的数据。
关于如何解决这个问题,我最好的猜测是不要为每个 sheet 实例化一个新的 SLDocument
,而是每次我想写一个特定的作品时使用 SLDocument.SelectWorksheet()
sheet,但我仍想将内容封装在 LogSheet class 中,因为其中的其他所有内容仍然相关。
还有其他建议吗?
推荐的有效方法是先将所有要写入的日志存储在内存中(使用 List<> 或其他东西)。然后写的时候,你select工作表,从第一个List<>开始写,select第二个工作表,从第二个List<>开始写,select第三个工作表,写第三个 List<>.
中的所有内容
如果内存有问题,则 select 第一个工作表,将日志块写入单元格值,select 第二个工作表,将日志块写入单元格值(将在第二个工作表中,因为第二个工作表当前是 selected),select 第三个工作表,写入日志块。然后用上面的方法遍历每个日志块。
后一种方法在任何时候都占用较少的内存,但需要更多的 CPU 周期,因为您一直在工作表之间来回切换。来回的事情相当于加载一个工作表,卸载它,然后加载另一个工作表等等。
我正在使用 SpreadsheetLight 从 WinForms 项目写入日志文件。我的意图是将日志条目写入同一文件中的三个工作 sheet,如果可以避免,我真的想避免使用 Interop
。
我从 Excel 中制作的模板文件开始,其中包含三个作品 sheet 和 pre-populated 的行标题,并且由于每个作品 sheet 具有相同的基本属性(可以独立变化),我将每个 sheet 封装在一个 class 中,其基础如下所示:
/// <summary>
/// Encapsulate the info we need to know about each worksheet in order to populate properly
/// </summary>
public class LogSheet
{
public SLDocument data;
public SLWorksheetStatistics stats;
public int RowCount;
public int ColumnCount;
public int currentColumn; //indicates what column you want to be writing to
public List<string> rowNames = new List<string>(); //used to make sure you're writing new data to the right row
public List<string> columnNames = new List<string>(); //used by GetLatestRun() to check if data already exists for a given serial number
public LogSheet(string sheet)
{
this.data = new SLDocument(_path, sheet);
this.stats = this.data.GetWorksheetStatistics();
this.RowCount = this.stats.EndRowIndex;
this.ColumnCount = this.stats.EndColumnIndex;
currentColumn = GetLatestRun();
for (int i = 1; i < RowCount + 1; i++)
{
this.rowNames.Add(this.data.GetCellValueAsString(i, 1));
}
for (int i = 1; i < ColumnCount + 1; i++)
{
this.columnNames.Add(this.data.GetCellValueAsString(1, i));
}
}
}
还有一些 LogSheet
class 中未显示的方法,用于将数据写入正确的位置。
这一切似乎工作正常,在调试时,我可以看到用 new LogSheet(<sheetName>)
实例化的三个工作 sheet 中的每一个都包含我编写后它们应该包含的数据给他们的东西。
问题是,当我想保存数据时,我可以逃脱this.data.Save()
,但它只保存了一个工作sheet,另外两个现在被搁置了,因为Save()
方法是终端并关闭 Excel 文件。在其他两个 sheet 中的任何一个上尝试 Save()
方法都以异常 "Object reference not set to an object"
结束,因为当然,Save()
杀死了我的传播 sheet,并且sheet 不再有任何参考。生成的文件只有我第一次保存时的数据。
关于如何解决这个问题,我最好的猜测是不要为每个 sheet 实例化一个新的 SLDocument
,而是每次我想写一个特定的作品时使用 SLDocument.SelectWorksheet()
sheet,但我仍想将内容封装在 LogSheet class 中,因为其中的其他所有内容仍然相关。
还有其他建议吗?
推荐的有效方法是先将所有要写入的日志存储在内存中(使用 List<> 或其他东西)。然后写的时候,你select工作表,从第一个List<>开始写,select第二个工作表,从第二个List<>开始写,select第三个工作表,写第三个 List<>.
中的所有内容如果内存有问题,则 select 第一个工作表,将日志块写入单元格值,select 第二个工作表,将日志块写入单元格值(将在第二个工作表中,因为第二个工作表当前是 selected),select 第三个工作表,写入日志块。然后用上面的方法遍历每个日志块。
后一种方法在任何时候都占用较少的内存,但需要更多的 CPU 周期,因为您一直在工作表之间来回切换。来回的事情相当于加载一个工作表,卸载它,然后加载另一个工作表等等。