从数据表创buildExcel工作表

我正面临一个奇怪的现象。 我写了一个方法,将数据表中的值复制到Excel表单中。 问题是行被复制到列和列到行。

例如:

数据表:

Item Quantity UnitPrice TotalPrice A 10 2 20 B 3 15 45 C 100 0.5 50 

Excel工作表:

 Item Quantity UnitPrice TotalPrice ABC 10 3 100 2 15 0.5 20 45 50 

我的代码:

  private void PopulateDataWorkSheet() { xl.Workbooks xlWorkbooks = _xlApp.Workbooks; xl.Workbook xlWorkbook = xlWorkbooks.Open(_excelFileName); xl.Sheets xlSheets = xlWorkbook.Sheets; const int startRowIndex = 2; // first row for columns title const int startColumnIndex = 1; xl.Worksheet xlDataWorkSheet = xlSheets[DATA_SHEET]; xl.Range xlCells = xlDataWorkSheet.Cells; for (var rowindex = 0; rowindex < _datatable.Rows.Count; rowindex++) { for (var columnindex = 0; columnindex < _datatable.Columns.Count; columnindex++) { xlCells[startRowIndex + rowindex][startColumnIndex + columnindex] = _datatable.Rows[rowindex][columnindex]; } } xlWorkbook.Save(); xlWorkbook.Close(); xlWorkbooks.Close(); ReleaseExcelObject(xlCells); ReleaseExcelObject(xlDataWorkSheet); ReleaseExcelObject(xlSheets); ReleaseExcelObject(xlWorkbook); ReleaseExcelObject(xlWorkbooks); } 

我可以简单地通过改变如下解决它,但我不清楚什么是错的:

 xlCells[startColumnIndex + columnindex][startRowIndex + rowindex] = _datatable.Rows[rowindex][columnindex]; 

我错过了我的代码中的东西?

我正面临一个奇怪的现象。 我错过了我的代码中的东西?

欢迎来到Excel Range ,dynamic,可选参数和COM对象的Default成员概念的世界。

Excel Range是一个奇怪的事情。 几乎每个方法/属性都返回另一个范围。 你使用的索引器是这样的

 dynamic this[object RowIndex, object ColumnIndex = Type.Missing] { get; set; } 

即需要行索引和可选的列索引。

让我们来打个电话

 xlCells[startRowIndex + rowindex][startColumnIndex + columnindex] = ...; 

这相当于这样的事情

 var range1 = (Excel.Range)xlCells[startRowIndex + rowindex]; var range2 = (Excel.Range)range1[startColumnIndex + columnindex]; // ^^^^^^ // this is treated as row index offset from the range1 range2.Value2 = ...; 

不久,你需要改变它

 xlCells[startRowIndex + rowindex, startColumnIndex + columnindex] = ...; 

你需要改变你如何访问你的Excel单元格。 cells[StartRowIndex+ rowindex, StartColumnIndex + columnindex]先行后列。 你所做的是cells[StartRowIndex + rowindex][StartColumnIndex + columnindex]将列作为第一个参数。

循环的顺序根本不重要..所以正确的解决scheme是:

  for (var rowindex = 0; rowindex < _datatable.Rows.Count; rowindex++) { for (var columnindex = 0; columnindex < _datatable.Columns.Count; columnindex++) { xlCells[startRowIndex + rowindex, startColumnIndex + columnindex] = _datatable.Rows[rowindex][columnindex]; } } 

干杯!

你做错了,你需要这样做:

  for (var columnindex = 0; columnindex < _datatable.Columns.Count; columnindex++) { for (var rowindex = 0; rowindex < _datatable.Rows.Count; rowindex++) { xlCells[startRowIndex + rowindex][startColumnIndex + columnindex] = _datatable.Rows[rowindex][columnindex]; } } 

你需要列然后行。

你可以使用下面的代码来解决这个问题。它对我来说工作的很好。

  xlApplication = new Microsoft.Office.Interop.Excel.Application(); // Create workbook . xlWorkBook = xlApplication.Workbooks.Add(Type.Missing); // Get active sheet from workbook xlWorkSheet = xlWorkBook.ActiveSheet; xlWorkSheet.Name = "Report"; xlWorkSheet.Columns.ColumnWidth = 30; xlApplication.DisplayAlerts = false; for (int rowIndex = 0; rowIndex < gridViewDataTable.Rows.Count; rowIndex++) { for (int colIndex = 0; colIndex < gridViewDataTable.Columns.Count; colIndex++) { if (rowIndex == 0) { xlWorkSheet.Cells[rowIndex + 1, colIndex + 1] = gridViewDataTable.Columns[colIndex].ColumnName; xlWorkSheet.Cells[rowIndex + 1, colIndex + 1].Interior.Color = System.Drawing.Color.LightGray; } xlWorkSheet.Cells[rowIndex + 2, colIndex + 1].Borders.Color = Color.Black; xlWorkSheet.Cells[rowIndex + 2, colIndex + 1].Interior.Color = System.Drawing.Color.White; xlWorkSheet.Cells[rowIndex + 2, colIndex + 1] = gridViewDataTable.Rows[rowIndex][colIndex]; } } xlWorkBook.SaveAs(filename); xlWorkBook.Close(); xlApplication.Quit();