Close/dispose 来自实例化方法外部的 Syncfusion XlsIO 实例
Close/dispose Syncfusion XlsIO instance from outside of instantiating method
我试图做的是将文件位置和工作sheet 名称传递给 Syncfusion 的 XLSIO 实例,并从中读取信息以驱动 C# 中的 Selenium 脚本。我做了那个工作。我 运行 在尝试将其分解为外部 类 时遇到了问题,因此我可以为 Selenium 脚本的不同部分调用不同的工作 sheet。
使用当前代码,我最终在 var range = worksheet.UsedRange;
处得到一个空对象,因为虽然成功传递了 sheet 对象,但基础对象(excel引擎和工作簿)有已从 ExcelDataReader 方法中处理掉。
如果我删除关闭并处理,它会按预期运行并登录。但是,我仍然需要清理,因为让 excel 实例和 spreadsheet 保持打开状态会在我稍后需要使用它时导致其他问题。
如果我在创建列表后尝试 close/dispose,对象不是该方法的一部分,它无法找到它们 close/dispose。
那么,即使我已经处理掉了引擎,我该如何传递列表创建方法所需的所有内容,或者如何在离开该方法后处理引擎?或者,我应该以不同的方式分解这些方法吗?
注意:我从列表创建中分离出 ExcelDataReader 的原因是因为我计划将该代码与传递给整个自动化项目的驱动程序不同部分的不同 sheet 参数一起使用。如果我不能完成这项工作,我将不得不将 ExcelDataReader 中的功能放入每个不同列表的列表创建块中。我可以做到,我知道它有效,但感觉很草率。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Syncfusion.XlsIO;
using System.IO;
using System.Data;
using System.Runtime.Remoting.Messaging;
namespace ConsoleApp7
{
public class Login
{
public string Usr { get; set; }
public string Pwd { get; set; }
}
public class DataFeed
{
public string FileName { get; set; }
public string Worksheet { get; set; }
}
interface IListBuilder
{
void BuildList(DataFeed feed);
}
enum ListType
{
LoginList,
UrlList,
}
public static class DoTheWork
{
public class LoginList : IListBuilder
{
public void BuildList(DataFeed feed)
{
var sheet = DoTheWork.ExcelDataReader(feed);
DoTheWork.loginList(sheet);
}
}
public static IWorksheet ExcelDataReader(DataFeed feed)
{
// instantiate Syncfusion xslio
ExcelEngine excelEngine = new ExcelEngine();
IApplication application = excelEngine.Excel;
//read file to stream
IWorkbook workbook = application.Workbooks.Open(feed.FileName);
// get worksheet
var sheet = workbook.Worksheets[feed.Worksheet];
workbook.Close();
excelEngine.Dispose();
return sheet;
}
public static List<Login> loginList(IWorksheet sheet)
{
var worksheet = sheet;
var range = worksheet.UsedRange;
List<Login> loginList = new List<Login>();
for (var i = 2; i <= range.LastRow; i++)
{
if (!string.IsNullOrEmpty(range[i, 1].Text) && !string.IsNullOrEmpty(range[i, 2].Text))
{
loginList.Add(new Login
{
Usr = range[i, 1].Text,
Pwd = range[i, 2].Text,
});
}
}
return loginList;
}
}
}
这就是我在 main 中调用它的方式:
IListBuilder list = new DoTheWork.LoginList();
DataFeed feed = new DataFeed
{
FileName = @"C:\source\repos\ConsoleApp7\TestData.xlsx",
Worksheet = "usr"
};
IWorksheet sheet = DoTheWork.ExcelDataReader(feed);
var logins = DoTheWork.loginList(sheet);
var xUserName = logins[0].Usr;
var xPassword = logins[0].Pwd;
我们建议在 ExcelDataReader 方法之外使用 IWorkbook.Close() 方法,如以下代码片段所示。
IWorksheet sheet = DoTheWork.ExcelDataReader(feed);
var logins = DoTheWork.loginList(sheet);
sheet.Workbook.Close(); // Closing the workbook
我们已经用您的代码片段准备了一个简单的示例来实现您的要求,可以从以下网址下载 link:
示例 Link:Sample
我试图做的是将文件位置和工作sheet 名称传递给 Syncfusion 的 XLSIO 实例,并从中读取信息以驱动 C# 中的 Selenium 脚本。我做了那个工作。我 运行 在尝试将其分解为外部 类 时遇到了问题,因此我可以为 Selenium 脚本的不同部分调用不同的工作 sheet。
使用当前代码,我最终在 var range = worksheet.UsedRange;
处得到一个空对象,因为虽然成功传递了 sheet 对象,但基础对象(excel引擎和工作簿)有已从 ExcelDataReader 方法中处理掉。
如果我删除关闭并处理,它会按预期运行并登录。但是,我仍然需要清理,因为让 excel 实例和 spreadsheet 保持打开状态会在我稍后需要使用它时导致其他问题。
如果我在创建列表后尝试 close/dispose,对象不是该方法的一部分,它无法找到它们 close/dispose。
那么,即使我已经处理掉了引擎,我该如何传递列表创建方法所需的所有内容,或者如何在离开该方法后处理引擎?或者,我应该以不同的方式分解这些方法吗?
注意:我从列表创建中分离出 ExcelDataReader 的原因是因为我计划将该代码与传递给整个自动化项目的驱动程序不同部分的不同 sheet 参数一起使用。如果我不能完成这项工作,我将不得不将 ExcelDataReader 中的功能放入每个不同列表的列表创建块中。我可以做到,我知道它有效,但感觉很草率。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Syncfusion.XlsIO;
using System.IO;
using System.Data;
using System.Runtime.Remoting.Messaging;
namespace ConsoleApp7
{
public class Login
{
public string Usr { get; set; }
public string Pwd { get; set; }
}
public class DataFeed
{
public string FileName { get; set; }
public string Worksheet { get; set; }
}
interface IListBuilder
{
void BuildList(DataFeed feed);
}
enum ListType
{
LoginList,
UrlList,
}
public static class DoTheWork
{
public class LoginList : IListBuilder
{
public void BuildList(DataFeed feed)
{
var sheet = DoTheWork.ExcelDataReader(feed);
DoTheWork.loginList(sheet);
}
}
public static IWorksheet ExcelDataReader(DataFeed feed)
{
// instantiate Syncfusion xslio
ExcelEngine excelEngine = new ExcelEngine();
IApplication application = excelEngine.Excel;
//read file to stream
IWorkbook workbook = application.Workbooks.Open(feed.FileName);
// get worksheet
var sheet = workbook.Worksheets[feed.Worksheet];
workbook.Close();
excelEngine.Dispose();
return sheet;
}
public static List<Login> loginList(IWorksheet sheet)
{
var worksheet = sheet;
var range = worksheet.UsedRange;
List<Login> loginList = new List<Login>();
for (var i = 2; i <= range.LastRow; i++)
{
if (!string.IsNullOrEmpty(range[i, 1].Text) && !string.IsNullOrEmpty(range[i, 2].Text))
{
loginList.Add(new Login
{
Usr = range[i, 1].Text,
Pwd = range[i, 2].Text,
});
}
}
return loginList;
}
}
}
这就是我在 main 中调用它的方式:
IListBuilder list = new DoTheWork.LoginList();
DataFeed feed = new DataFeed
{
FileName = @"C:\source\repos\ConsoleApp7\TestData.xlsx",
Worksheet = "usr"
};
IWorksheet sheet = DoTheWork.ExcelDataReader(feed);
var logins = DoTheWork.loginList(sheet);
var xUserName = logins[0].Usr;
var xPassword = logins[0].Pwd;
我们建议在 ExcelDataReader 方法之外使用 IWorkbook.Close() 方法,如以下代码片段所示。
IWorksheet sheet = DoTheWork.ExcelDataReader(feed);
var logins = DoTheWork.loginList(sheet);
sheet.Workbook.Close(); // Closing the workbook
我们已经用您的代码片段准备了一个简单的示例来实现您的要求,可以从以下网址下载 link:
示例 Link:Sample