我试图使用spire.XLS将windows窗体应用程序上的数据视图的手动选定的行导出到excel文件中,并在最后一行中添加最后一列的和。datagridview数据如下所示:

当我在选择第1行和最后一行后运行代码时,excel应该如下所示:

这是我的代码:
void ExportBtnXLSXClick(object sender, EventArgs e)
{
Workbook book = new Workbook();
Worksheet sheet = book.Worksheets[0];
sheet.Name = "Exported from gridview";
//Convert data from datagridview to datatable
DataTable dt=GetDgvToTable(dataGridView1);
//Export datatable to excel
sheet.InsertDataTable(dt, true, 1, 1, -1, -1);
//sheet.InsertDataTable(dt, true, 1, 1, true);
sheet.Range[1,1,sheet.LastRow,sheet.LastColumn].AutoFitColumns();
sheet.AllocatedRange.BorderAround(LineStyleType.Thin, borderColor:ExcelColors.Black);
sheet.AllocatedRange.BorderInside(LineStyleType.Thin, borderColor:ExcelColors.Black);
book.SaveToFile(@"C:\Users\Tamal\Desktop\Spire.XLS C#\Report.xlsx", ExcelVersion.Version2013);
book.Dispose();
MessageBox.Show("Export complete");
}使用助手方法
public DataTable GetDgvToTable(DataGridView dgv)
{
DataTable dt = new DataTable();
//Column
for (int count = 0; count < dgv.Columns.Count; count++)
{
DataColumn dc = new DataColumn(dgv.Columns[count].Name.ToString());
dt.Columns.Add(dc);
}
//Row
for (int count = 0; count < dgv.SelectedRows.Count; count++)
{
DataRow dr = dt.NewRow();
for (int countsub = 0; countsub < dgv.Columns.Count; countsub++)
//for (int countsub = 0; countsub < dgv.SelectedRows.Count; countsub++)
{
dr[countsub] = Convert.ToString(dgv.Rows[count].Cells[countsub].Value);
}
dt.Rows.Add(dr);
}
decimal total = dataGridView1.SelectedRows.OfType<DataGridViewRow>()
.Sum(t => Convert.ToDecimal(t.Cells[2].Value));
dt.Rows.Add(total);
return dt;
}但是它没有显示我选择的两行,也没有显示在excel最后一行的第一列上。我怎样才能得到想要的结果?
另外,如果我多次运行代码,那么数据不应该被覆盖,而只是在最后一个填充的行之后粘贴数据,最好在中间保留一行空白。
下面是datagridview的样子:

请帮帮忙
发布于 2021-03-27 20:32:04
你有很多问题要问。首先,如果要向同一个工作簿添加多个选择,则需要执行一些不同的操作(…)。
如果文件已经存在,则在打开文件后,需要检查工作表“从网格视图导出”是否存在
目前,代码只是简单地“创建”一个新的工作簿,然后代码将覆盖现有的工作簿(如果它已经存在)。因此,如果要向“相同”工作簿“添加”其他选择,则需要添加检查文件是否存在的代码,如果存在,则在工作表上找到下一个可用行,将附加项添加到上面的三个步骤中。
下面是一个简单的示例,但是它没有经过很好的测试,我相信您可能需要调整代码以满足您的需求。
首先,在GetDgvToTable方法中,在创建表…时,代码似乎抓住了错误的行。。
for (int count = 0; count < dgv.SelectedRows.Count; count++)
{
DataRow dr = dt.NewRow();
for (int countsub = 0; countsub < dgv.Columns.Count; countsub++)
//for (int countsub = 0; countsub < dgv.SelectedRows.Count; countsub++)
{
dr[countsub] = Convert.ToString(dgv.Rows[count].Cells[countsub].Value);
}
dt.Rows.Add(dr);
}上面,代码循环通过“选定的行数”。问题就在…上
dr[countsub] = Convert.ToString(dgv.Rows[count].Cells[countsub].Value);具体来说,在…
dgv.Rows[count].这里的代码忽略了“选定的”行。换句话说,如果“选定”行是从“第一”行(0)开始的连续“选定”行,那么它将工作。不幸的是,第一个“选定的”行可能不一定是网格中的“第一个”行。代码错误地做出了这样的假设。
要解决这一问题,我建议您使用foreach循环遍历“选定的”行,然后通过网格SelectedRows集合循环。这将确保代码使用“选定的”行。代码更改看起来类似于…
foreach (DataGridViewRow row in dgv.SelectedRows) {
DataRow dr = dt.NewRow();
for (int i = 0; i < row.Cells.Count; i++) {
dr[i] = row.Cells[i].Value.ToString();
}
dt.Rows.Add(dr);
}接下来,您将声明要将其他选择添加到同一工作表中,在选择之间有一个空行。上文曾讨论过这一点。在下面的代码中,它检查Excel文件是否已经存在,如果已经存在,则打开该文件。接下来进行检查,以确定工作表是否已经存在。如果它不存在,则创建一个新的。
接下来,进行检查,查看是否已经将“先前”选择添加到工作表中。我对Spire并不那么熟悉,但是,我注意到如果您调用…方法
sheet.LastRow…它将返回下一个可用行…除非工作表是空的。当工作表为空时,这将返回一个类似于65,570的值。我会把这个留给你,也许你会想出一种更优雅的方法来得到下一个空行。在这种情况下,我只需检查sheet.LastRow是否超过60000。如果值超过60000,则假设工作表为空,只需将下一个可用行设置为1。我确信有更好的方法可以做到这一点。
在所有这些情况下,下面对这两种方法的更改似乎都是按照您的要求进行的,方法是将附加的选择添加到“前面选择的”相同工作表中。
public DataTable GetDgvToTable(DataGridView dgv) {
DataTable dt = new DataTable();
//Column
for (int count = 0; count < dgv.Columns.Count; count++) {
DataColumn dc = new DataColumn(dgv.Columns[count].Name.ToString());
dt.Columns.Add(dc);
}
//Row
foreach (DataGridViewRow row in dgv.SelectedRows) {
DataRow dr = dt.NewRow();
for (int i = 0; i < row.Cells.Count; i++) {
dr[i] = row.Cells[i].Value.ToString();
}
dt.Rows.Add(dr);
}
decimal total = dataGridView1.SelectedRows.OfType<DataGridViewRow>()
.Sum(t => Convert.ToDecimal(t.Cells[2].Value));
dt.Rows.Add("","Total",total);
return dt;
}然后是对导出方法的更改。
private void btnExportToExcel_Click(object sender, EventArgs e) {
Workbook book = new Workbook();
if (File.Exists(@"pathToFile\Report.xlsx")) {
book.LoadFromFile(@"pathToFile\Report.xlsx");
}
Worksheet sheet = book.Worksheets["Exported from gridview"];
if (sheet == null) {
sheet = book.CreateEmptySheet("Exported from gridview");
}
//Convert data from datagridview to datatable
DataTable dt = GetDgvToTable(dataGridView1);
//Export datatable to excel
int startRow = sheet.LastRow + 2;
if (startRow > 60000) {
startRow = 1;
}
sheet.InsertDataTable(dt, true, startRow, 1, -1, -1);
sheet.Range[1, 1, sheet.LastRow, sheet.LastColumn].AutoFitColumns();
sheet.AllocatedRange.BorderAround(LineStyleType.Thin, borderColor: ExcelColors.Black);
sheet.AllocatedRange.BorderInside(LineStyleType.Thin, borderColor: ExcelColors.Black);
book.SaveToFile(@"pathToFile\Report.xlsx", ExcelVersion.Version2013);
book.Dispose();
MessageBox.Show("Export complete");
}我希望这是合理的,也是有帮助的。
https://stackoverflow.com/questions/66834292
复制相似问题