根据列名

时间:2015-06-30 16:42:19

标签: c# excel

我正在寻找一种方法来更新现有的Excel电子表格,其中包含来自SQL查询的数据,通过C#将数据放入基于列标题的列中。例如,如果我有以下返回的查询/数据集

Width    Height    Length
  2        2          2     
  2        3          4
  3        4          5

我有一个像这样的Excel工作簿:

Width    Height       Area      Length     Volume
                    =(A1*B1)              =(C1*D1)
                    =(A2*B2)              =(C2*D2)
                    =(A3*B3)              =(C3*D3)

我想在工作簿中插入Width,Length和Height而不影响Area或Volume,即:

Width    Height       Area      Length     Volume
  2        2        =(A1*B1)      2       =(C1*D1)
  2        3        =(A2*B2)      4       =(C2*D2)
  3        4        =(A3*B3)      5       =(C3*D3)

有没有办法在代码中指定数据集的宽度应该放在Width列等中?我目前正在使用EPPlus包来执行Excel任务。

2 个答案:

答案 0 :(得分:0)

有两种方法 1.您可以硬编码Excel列名称的索引 你可以解决它并把它放在字典中

我打算选择2,这对你来说更容易。但是有几个假设。

  • 您知道如何通过Interop.Excel
  • 获取应用程序的Worksheet属性
  • 您可以指定开始输入数据的行,以及所有列名称所在的行

这是代码

using Microsoft.Office.Interop.Excel;

public void SyncData(Worksheet ws, DataTable dt, int startRow){
    //Get the columns and their corresponding indexes in excel
    Dictionary<string, int> columnMap = ExcelColumnResolver(ws, dt, 1);

    //The row number in excel youre starting to update from
    int currRow = startRow;

    //Iterate through the rows and the columns of each row
    foreach(DataRow row in dt.Rows){
        foreach(DataColumn column in dt.Columns){

            //Only update columns we have mapped
            if(columnMap.ContainsKey(column.ColumnName)){
                ws.Cells[currRow, columnMap[column.ColumnName]] = row[column.ColumnName];
            }
        }

        currRow++;
    }
}

//columnsRow = Row in which the column names are located (non-zero indexed)
public Dictionary <string, int> ExcelColumnResolver(Worksheet ws, DataTable dt, int columnsRow) {
    Dictionary<string, int> nameToExcelIdxMap = new Dictionary<string, int>();

    //The row in Excel that your column names are located
    int maxColumnCount = 10;

    //Excel cells start at index 1
    for (int i = 1; i < maxColumnCount; i++) {
        string col = ws.Cells[columnsRow, i].ToString();

        if (dt.Columns.Contains(col)){
            nameToExcelIdxMap[col] = i;
        }
    }

    return nameToExcelIdxMap;
}

这是关于如何访问Excel工作表的tutorial

运行时间为O(n ^ 2),但为了性能,我建议:

答案 1 :(得分:0)

使用 EPPlus 并假设 GetDataFromSql 返回 DataTable ,您可以使用以下代码:

var data = GetDataFromSql();

using (var excelPackage = new ExcelPackage(new FileInfo(@"C:\Proj\Sample\Book1.xlsx")))
{
    var worksheet = excelPackage.Workbook.Worksheets.First();

    // Get locations of column names inside excel:
    var headersLocation = new Dictionary<string, Tuple<int, int>>();
    foreach (DataColumn col in data.Columns)
    {
        var cell = worksheet.Cells.First(x => x.Text.Equals(col.ColumnName));
        headersLocation.Add(col.ColumnName, new Tuple<int, int>(cell.Start.Row, cell.Start.Column));
    }

    for (var i = 0; i < data.Rows.Count; i++)
    {
        foreach (DataColumn col in data.Columns)
        {
            // update the value
            worksheet.Cells[headersLocation[col.ColumnName].Item1 + i + 1,
                headersLocation[col.ColumnName].Item2
                ].Value = data.Rows[i][col];
        }
    }

    excelPackage.Save();
}