C#DataGridView到Excel文件错误
我已经编写了下面的YouTube教程,教程中的DataSource是一个AOD.NET实体数据模型,我已经使用了Access数据库。 我已经编译的代码,但得到各种类似的错误
The name 'productBindingSource' does not exist in the current context
要么
The name 'DB' does not exist in the current context
要么
The type or namespace name 'Product' could not be found
我不确定是否错过了添加引用,或者这些错误是由于数据源不同造成的?
Visual Studio自动添加了//TODO: This line of code etc...
,我把它改成它在教程中显示的样子。
我希望有人能帮我看看我做错了什么?
教程: https : //www.youtube.com/watch?v = -wGzK1vsqS8
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; namespace ExportWebsiteData { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void label1_Click(object sender, EventArgs e) { } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { List<Product> list = ((DataParameter)e.Argument).ProductList; string filename = ((DataParameter)e.Argument).FileName; Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application(); Workbook wb = excel.Workbooks.Add(XlSheetType.xlWorksheet); Worksheet ws = (Worksheet)excel.ActiveSheet; excel.Visible = false; int index = 1; int process = list.Count; //Add Column ws.Cells[1, 1] = "Item Number"; ws.cells[1, 2] = "Model"; ws.cells[1, 3] = "Manufacturer"; ws.cells[1, 4] = "Category"; ws.cells[1, 5] = "Subcategory"; // foreach(Product p in list) { if (!backgroundWorker.CancellationPending) { backgroundWorker.ReportProgress(index++ * 100 / process); ws.Cells[index, 1] = p.ItemNumber.ToString(); ws.Cells[index, 2] = p.Model.ToString(); ws.Cells[index, 3] = p.Manufacturer.ToString(); ws.Cells[index, 4] = p.Category.ToString(); ws.Cells[index, 5] = p.SubCategory.ToString(); } } //Save file ws.SaveAs(filename, XlFileFormat.xlWorkbookdefault, Type.Missing, Type.Missing, true, false, XlSaveConflictResolution.xlLocalSessionChanges, Type.Missing, Type.Missing); excel.Quit(); } struct DataParameter { public List<Product> ProductList; public string FileName { get; set; } } DataParameter _inputParameter; private void Form1_Load(object sender, EventArgs e) { using (this.inventoryTableAdapter.Fill(this._Wizard_Data_2016_10_17DataSet.Inventory); = new _Wizard_Data_2016_10_17DataSet()) { productBindingSource.DataSource = DB.Products.ToList(); } // TODO: This line of code loads data into the '_Wizard_Data_2016_10_17DataSet.Inventory' table. You can move, or remove it, as needed. //this.inventoryTableAdapter.Fill(this._Wizard_Data_2016_10_17DataSet.Inventory); } private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar.Value = e.ProgressPercentage; lblStatus.Text = string.Format("Processing...{0}", e.ProgressPercentage); progressBar.Update(); } private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if(e.Error == null) { Thread.Sleep(100); lblStatus.Text = "Your data has been successfully exported."; } } private void btnExport_Click(object sender, EventArgs e) { if (backgroundWorker.IsBusy) return; using (SaveFileDialog sfd = new SaveFileDialog() { Filter = "Excel Workbook|*.xls" }) { if (sdf.ShowDialog() == DialogResult.OK) { _inputParameter.FileName = sfd.FileName; _inputParameter.ProductList = productBindingSource.DataSource as List<product>; progressBar.Minimum = 0; progressBar.Value = 0; backgroundWorker.RunWorkerAsync(_inputParameter); } } } } }
更新:
John的答案确实解决了我的错误,但数据网格现在正在由cs代码而不是数据库填充。 如果有人能让我知道他们认为是什么问题,我已经做了一个更详细的解释问题的video。
https://www.dropbox.com/s/1l5iw1j32a6oroj/C%23Excel.wmv?dl=0
从发布的代码有几个错误和错别字。 看起来在获取数据的Form1_Load
方法中存在一些问题。 为了解决这个问题,并且由于看起来使用的数据是Product
对象列表,下面的代码使用Product
对象List
。 该列表然后填充一些testing数据。 这个testing数据将被用作DataGridView
一个DataSource
。 一旦数据在DataGridView
,导出button将成功地将数据从DataGridView
导出到Excel工作簿。
在以上发布的代码中input错字:
ws.Cells[1, 1] = "Item Number"; ws.cells[1, 2] = "Model";
小写“C”表示第2,3,4,5列的单元格会抛出未定义错误的定义。
ws.SaveAs(filename, XlFileFormat.xlWorkbookdefault, ……);
以上这个可能取决于版本, xlWorkbookdefault
应该有一个大写的“D”:
XlFileFormat.xlWorkbookDefault
最后的错字是在SaveFileDialog
的ShowDialog
中
SaveFileDialog sfd = new SaveFileDialog()
然后下一行尝试使用:
sdf.ShowDialog()
上面的行应该是“sfd”而不是“sdf”。
看着你张贴的图片,显示错误,并观看你链接的video后,有一些video可能错过的东西。 从顶部开始,似乎有一种叫做Product
东西缺less其定义。 这看起来像一个类,从代码看来,该类具有项目编号,模型,制造商,类别和子类别。 我不确定该video是否忽略了这一点,或者Product
是我缺less的其他东西。 在这种情况下,为了解决这个缺失的定义,下面的代码使用上面的属性创build了一个Product
类。
public class Product { public string ItemNumber { get; set; } public string Model { get; set; } public string Manufacturer { get; set; } public string Category { get; set; } public string SubCategory { get; set; } public Product(string iNum, string model, string manuf, string cat, string subCat) { ItemNumber = iNum; Model = model; Manufacturer = manuf; Category = cat; SubCategory = subCat; }
接下来的2个错误(XlFileFormat和XlSaveConflictResolution)是由于在代码中缺lessusing语句而生成的。 这似乎被排除在video之外。 要修复这两个错误,请将下面的行放在使用语句所在文件的顶部。
using Microsoft.Office.Interop.Excel;
错误:int:在使用语句中使用的types…请参阅下面的表单加载。
这两个错误productBindingSource
不存在。 video放置了一个BackgroundWorker
的表单,但我没有看到一个BindingSource
放置。 为了解决这个问题…在devise器中,从工具箱中select一个BindingSource
组件,并将其放到窗体上,然后将其名称更改为productBindingSource
。
“DB”错误将被注释掉以使用产品对象列表。 请参阅下面的Form_Load。
“线程”错误表示缺less使用语句:将下面的行与其他使用语句放在一起。
using System.Threading;
上面已经介绍了“sdf”。 最后一个错误来自以下行:
productBindingSource.DataSource as List<product>;
product
应该有一个大写的“P”: List<Product>;
通过上面所做的更改,唯一的错误应该是Form_Load方法。
private void Form1_Load(object sender, EventArgs e) { using (this.inventoryTableAdapter.Fill(this._Wizard_Data_2016_10_17DataSet.Inventory); = new _Wizard_Data_2016_10_17DataSet()) { productBindingSource.DataSource = DB.Products.ToList(); } }
上面的行格式不正确,但似乎试图获得一个DataSet
。 我稍后会留下来供你考虑。 由于productBindingSource
似乎正在接受产品对象列表,因此代码replace了该产品,并为testing数据创build了产品对象列表。 Form_Load
方法更改为下面的代码,将productBindingSource
设置为testing数据列表,然后将此绑定源指定为DataGridView
的DataSource
。 video中缺less这一点。
private void Form2_Load(object sender, EventArgs e) { List<Product> list = GetProductList(); productBindingSource.DataSource = list; dataGridView1.DataSource = productBindingSource; }
通过上述更改,代码可按预期的方式导出。 希望这可以帮助。
private List<Product> GetProductList() { List<Product> products = new List<Product>(); for (int i = 0; i < 14; i++) { products.Add(new Product(i.ToString(), "Model_" + i, "Manufacture_" + i, "Cat_" + i, "SubCat_" + i)); } return products; }
编辑更新以从访问数据库获取表而不使用类
System.Data.DataTable dt = new System.Data.DataTable(); public Form2() { InitializeComponent(); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { //List<Product> list = ((DataParameter)e.Argument).ProductList; System.Data.DataTable list = ((DataParameter)e.Argument).ProductList; string filename = ((DataParameter)e.Argument).FileName; Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application(); Workbook wb = excel.Workbooks.Add(XlSheetType.xlWorksheet); Worksheet ws = (Worksheet)excel.ActiveSheet; excel.Visible = false; int index = 1; //int process = list.Count; int process = list.Rows.Count; //Add Column ws.Cells[1, 1] = "Item Number"; ws.Cells[1, 2] = "Model"; ws.Cells[1, 3] = "Manufacturer"; ws.Cells[1, 4] = "Category"; ws.Cells[1, 5] = "Subcategory"; foreach (DataRow dr in list.Rows) { if (!backgroundWorker.CancellationPending) { backgroundWorker.ReportProgress(index++ * 100 / process); ws.Cells[index, 1] = dr.ItemArray[1].ToString(); ws.Cells[index, 2] = dr.ItemArray[2].ToString(); ws.Cells[index, 3] = dr.ItemArray[3].ToString(); ws.Cells[index, 4] = dr.ItemArray[4].ToString(); ws.Cells[index, 5] = dr.ItemArray[5].ToString(); } } //Save file ws.SaveAs(filename, XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing, true, false, XlSaveConflictResolution.xlLocalSessionChanges, Type.Missing, Type.Missing); excel.Quit(); } struct DataParameter { public System.Data.DataTable ProductList; public string FileName { get; set; } } DataParameter _inputParameter; private void Form2_Load(object sender, EventArgs e) { string ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\Test\Test3.accdb"; using (OleDbConnection olcon = new OleDbConnection(ConnectionString)) { using (OleDbDataAdapter adapter = new OleDbDataAdapter()) { string command = "SELECT * FROM [Products]"; //cmd.CommandText = "SELECT * FROM [" + sheetName + "]"; OleDbCommand cmd = new OleDbCommand(command, olcon); //Fill Gridview with Data from Access try { dt.Clear(); adapter.SelectCommand = cmd; adapter.Fill(dt); productBindingSource.DataSource = dt; dataGridView1.DataSource = productBindingSource; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } finally { olcon.Close(); var totalWidth = dataGridView1.Columns.GetColumnsWidth(DataGridViewElementStates.None); } } } } private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar.Value = e.ProgressPercentage; lblStatus.Text = string.Format("Processing...{0}", e.ProgressPercentage); progressBar.Update(); } private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Error == null) { Thread.Sleep(100); lblStatus.Text = "Your data has been successfully exported."; } } private void btnExport_Click(object sender, EventArgs e) { if (backgroundWorker.IsBusy) return; using (SaveFileDialog sfd = new SaveFileDialog() { Filter = "Excel Workbook|*.xls" }) { if (sfd.ShowDialog() == DialogResult.OK) { _inputParameter.FileName = sfd.FileName; //_inputParameter.ProductList = GetProductsList2(); _inputParameter.ProductList = (System.Data.DataTable)productBindingSource.DataSource; progressBar.Minimum = 0; progressBar.Value = 0; backgroundWorker.RunWorkerAsync(_inputParameter); } } }