我创建了一个应用来帮助我重新排列excel文件中的列。问题是,当我保存文件时,即使datagridview是我想要的,导出的文件也与初始文件完全相同。
有人能让我知道我哪里错了吗?
以下是代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel;
using System.IO;
using Microsoft.Office.Tools.Excel;
using System.Data.SqlClient;
using System.Configuration;
namespace ReadExcelFiles
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DataSet result;
private void btnOpen_Click(object sender, EventArgs e)
{
//==========================================================
//CODE FOR IMPORTING DATA TO DATAGRIDVIEW===================
//==========================================================
using (OpenFileDialog ofd = new OpenFileDialog() { Filter = "Excel Workbook|*.xls", ValidateNames = true })
{
if (ofd.ShowDialog() == DialogResult.OK)
{
FileStream fs = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read);
IExcelDataReader reader = ExcelReaderFactory.CreateBinaryReader(fs);
reader.IsFirstRowAsColumnNames = true;
result = reader.AsDataSet();
cboSheet.Items.Clear();
foreach (DataTable dt in result.Tables)
cboSheet.Items.Add(dt.TableName);
reader.Close();
}
}
}
private void cboSheet_SelectedIndexChanged(object sender, EventArgs e)
{
//================================================
//CODE FOR SHEET FILTER===========================
//================================================
dataGridView.DataSource = result.Tables[cboSheet.SelectedIndex];
}
private void btnArg_Click(object sender, EventArgs e)
{
//==============================================
//CODE FOR COLUMN SORTING ======================
//==============================================
dataGridView.Columns["BUYER_NAME"].DisplayIndex = 0;
dataGridView.Columns["PO_NUMBER"].DisplayIndex = 1;
dataGridView.Columns["PO_LINE_NUMBER"].DisplayIndex = 2;
dataGridView.Columns["VENDOR_NAME"].DisplayIndex = 3;
dataGridView.Columns["INVOICE_NUM"].DisplayIndex = 4;
dataGridView.Columns["INVOICE_DATE"].DisplayIndex = 5;
dataGridView.Columns["HOLD_LOOKUP_CODE"].DisplayIndex = 6;
dataGridView.Columns["AGING_DAYS"].DisplayIndex = 7;
dataGridView.Columns["INVOICE_AMOUNT"].DisplayIndex = 8;
dataGridView.Columns["INVOICE_CURRENCY_CODE"].DisplayIndex = 9;
dataGridView.Columns["INVOICE_CREATION_DATE"].DisplayIndex = 10;
dataGridView.Columns["TERMS"].DisplayIndex = 11;
dataGridView.Columns["BASE_AMOUNT"].DisplayIndex = 12;
dataGridView.Columns["OU"].DisplayIndex = 13;
dataGridView.Columns["SOURCE"].DisplayIndex = 14;
dataGridView.Columns["STYLE_NAME"].DisplayIndex = 15;
dataGridView.Columns["INVOICE_ID"].DisplayIndex = 16;
dataGridView.Columns["HELD_BY"].DisplayIndex = 17;
dataGridView.Columns["FULL_NAME_HELD_BY"].DisplayIndex = 18;
dataGridView.Columns["CURRENT_MARKVIEW_OWNER"].DisplayIndex = 19;
dataGridView.Columns["BUYER_ORG"].DisplayIndex = 20;
dataGridView.Columns["LAST_UPDATED_BY"].DisplayIndex = 21;
dataGridView.Columns["FULL_NAME_LAST_UPDATED_BY"].DisplayIndex = 22;
}
private void btnSave_Click(object sender, EventArgs e)
{
//================================================
//CODE TO EXPORT DATAGRID TO EXCEL======= ========
//================================================
// Creating a Excel object.
Microsoft.Office.Interop.Excel._Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
try
{
worksheet = workbook.ActiveSheet;
worksheet.Name = "ExportedFromDatGrid";
int cellRowIndex = 1;
int cellColumnIndex = 1;
//Loop through each row and read value from each column.
for (int i = 0; i < dataGridView.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridView.Columns.Count; j++)
{
// Excel index starts from 1,1. As first Row would have the Column headers, adding a condition check.
if (cellRowIndex == 1)
{
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Columns[j].HeaderText;
}
else
{
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i].Cells[j].Value.ToString();
}
cellColumnIndex++;
}
cellColumnIndex = 1;
cellRowIndex++;
}
//Getting the location and file name of the excel to save from user.
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
saveDialog.FilterIndex = 2;
if (saveDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
workbook.SaveAs(saveDialog.FileName);
MessageBox.Show("Export Successful");
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
excel.Quit();
workbook = null;
excel = null;
}
}
}
}
答案 0 :(得分:0)
除了重新组织Excel工作表中的列之外,还不清楚您需要在此处实现什么。我怀疑你为什么要使用两个不同的Excel库?第三方Lib打开excel文件,然后使用Interop
保存文件?对于你的问题,这真的无关紧要。
您为此引入DataGridView
似乎很奇怪。如果要将Excel工作表中的列重新排序为新的Excel文件...只需打开excel源文件,创建新的Excel文件并根据需要复制列。似乎没有必要在这张图片中引入DataGridView
。
如果您需要将数据放在DataGridView
中以便重新排序列(就像您一样),那么您需要了解设置DataGridView
时会发生什么DataSource
。当您使用以下行时:
dataGridView.DataSource = result.Tables[cboSheet.SelectedIndex];
上面的行将DataGridView
的数据源设置为在组合框中选择的表。当DataGridView
绑定到DataTable
时,DataGridView
中的实际单元格无法像您想象的那样真正访问。如果您重新排列DataGridView
的列(我假设您使用的是btnArg_Click
事件),则DataGridView
中的列会发生变化,但数据表中的列不同网格绑定...它不会改变。因此,当您遍历DataGridView
并解决每个单元格时,如下所示:...
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i].Cells[j].Value.ToString();
这会将i
和j
与DATA TABLE匹配,并且由于它没有更改,因此您将获得与之相同的excel工作表。当您更改DataGridView
列的顺序时,我假设您正在使用以下代码:
private void btnArg_Click(object sender, EventArgs e) {
dataGridView.Columns["BUYER_NAME"].DisplayIndex = 0;
dataGridView.Columns["PO_NUMBER"].DisplayIndex = 1;
.
.
.
...数据表的索引与DataGridView
中的索引不匹配。数据表保持不变,不会更改。由于您已经方便地将列DisplayIndex
设置为所需列,因此我们可以使用它来确定在创建新的Excel文件时要抓取的列。
使用DisplayIndex
值(尽可能减少)更改为btnSave_Click
代码。它应该按预期工作,但我相信有可能更容易实现这一目标。简单地重新排序DataTable
列可能更容易。只是一个建议......可能不是最好的建议。你可能想看一下LINQ。
以下代码的更改包括: 1)添加
excel.Visible = true;
显示新excel文件的创建。
2)添加了int
变量tableCol:
int tableCol = -1;
它用于获取当前列DisplayIndex
以获取正确的列,因为它们已针对DataGridView
进行了更改。
3)在将数据写入新的Excel工作表时,更改了double for循环中的2行。行标题的第一行和数据的第二行。由于您使用相同的循环来获取标题,我们需要在第二行递减“i”;否则你会错过第一排。同样,这是一个hacky方法,可能更容易简单地首先在自己的循环中打印标题。
// Headers
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Columns[tableCol].HeaderText;
// Data
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i-1].Cells[tableCol].Value.ToString();
更新了btn_Save事件:
private void btnSave_Click(object sender, EventArgs e) {
//================================================
//CODE TO EXPORT DATAGRID TO EXCEL======= ========
//================================================
// Creating a Excel object.
Microsoft.Office.Interop.Excel._Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
excel.Visible = true;
try {
worksheet = workbook.ActiveSheet;
worksheet.Name = "ExportedFromDatGrid";
int cellRowIndex = 1;
int cellColumnIndex = 1;
int tableCol = -1;
//Loop through each row and read value from each column.
for (int i = 0; i < dataGridView.Rows.Count; i++) {
for (int j = 0; j < dataGridView.Columns.Count; j++) {
// Excel index starts from 1,1. As first Row would have the Column headers, adding a condition check.
tableCol = dataGridView.Columns[j].DisplayIndex;
if (cellRowIndex == 1) {
//worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Columns[j].HeaderText;
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Columns[tableCol].HeaderText;
}
else {
//worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i].Cells[j].Value.ToString();
worksheet.Cells[cellRowIndex, cellColumnIndex] = dataGridView.Rows[i-1].Cells[tableCol].Value.ToString();
}
cellColumnIndex++;
}
cellColumnIndex = 1;
cellRowIndex++;
}
//Getting the location and file name of the excel to save from user.
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
saveDialog.FilterIndex = 2;
if (saveDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
workbook.SaveAs(saveDialog.FileName);
MessageBox.Show("Export Successful");
}
}
catch (System.Exception ex) {
MessageBox.Show(ex.Message);
}
finally {
excel.Quit();
workbook = null;
excel = null;
}
}
希望这有帮助!