在c#中读取Excel,其中一些列为空

时间:2015-10-28 11:06:38

标签: c# excel datatable

我有一个像这样的Excel模板

enter image description here

我在阅读时遇到一些问题(我不能使用第三方库)。我的解决方案:

public partial class CaricaDocumento : System.Web.UI.Page
{

    static string HDR; // "Yes" indicates that the first row contains column names, not data
    Regex regex = new Regex("([0-9]+)(.*)");


    protected void Page_Load(object sender, EventArgs e)
    {
        string ind = "C:\\My_Template.xlsx";
        string sheetName = "Page1";

        DataTable dt = FromXLSX(ind, sheetName, true); 

        DataToView(dt);
    }


    // Bind data to the page
    private void DataToView(DataTable dt)
    {
        LblFattura.Text = GetValue("AO10", dt);
        LblDataFattura.Text = GetValue("AX10", dt);
        LblCognomeOrRagioneSociale.Text = GetValue("B18", dt);
        LblNome.Text = GetValue("AB18", dt);
    }


    // return the value from the cell, indicate a code like "A1", "B3", "AO10"...
    public string GetValue(string codeCell, DataTable dt)
    {
        string[] substrings = regex.Split(codeCell);
        string letterString = substrings[0]; // 'A' or 'B' ... 'AZ' ... 
        int letter = ColumnLetterToNumber(letterString); // transform the letter in a column index

        int num = 1;
        if (HDR == "Yes")
            num = 2;

        // if the first row is an header, do -2
        // if the first row is a simple data row, do -1
        int number = Int32.Parse(substrings[1]) - num; // the right row index
        return dt.Rows[number][letter].ToString();
    }


    //  transform the letter in a column index
    public static int ColumnLetterToNumber(string columnName)
    {
        if (string.IsNullOrEmpty(columnName)) throw new ArgumentNullException("columnName");

        columnName = columnName.ToUpperInvariant();

        int sum = 0;
        for (int i = 0; i < columnName.Length; i++)
        {
            sum *= 26;
            char letter = columnName[i];
            sum += (letter - ('A' - 1));
        }
        sum--;
        return sum;
    }


    // return the DataTable
    public static DataTable FromXLSX(string filePath, string sheet, bool hasHeaders)
    {
        try
        {
            // Create the new datatable.
            DataTable dtexcel = new DataTable();

            // Define the SQL for querying the Excel spreadsheet.
            HDR = hasHeaders ? "Yes" : "No"; // "HDR=Yes;" indicates that the first row contains column names, not data
            string IMEX = "1";

            string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath 
                    + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=" + IMEX + ";\"";

            // Create connection:
            OleDbConnection conn = new OleDbConnection(strConn);
            conn.Open();

            if (!sheet.EndsWith("_"))
            {
                // Query data from the sheet
                string query = "SELECT  * FROM [" + sheet + "$]";
                OleDbDataAdapter daexcel = new OleDbDataAdapter(query, conn);
                dtexcel.Locale = CultureInfo.CurrentCulture;

                // Fill the datatable:
                daexcel.Fill(dtexcel);
            }

            // Close connection.
            conn.Close();

            // Set the datatable.
            return dtexcel;
        }
        catch { throw; }
    }
}

但我注意到了这个问题:如果数据不是从'A'列开始, DataTable从第一列读取数据!是指数的噩梦。例如:

enter image description here

...在这种情况下,忽略列'A'(DataTable从'B'开始采用数据),这使得单元代码的使用无效(如“A1”,“B5”,“AO11”.. 。)因为方法ColumnLetterToNumber(string columnName)被扭曲了。

有人知道我如何强制DataTable从'A'列开始获取数据?或者使用单元代码从Excel获取数据的其他方法?

1 个答案:

答案 0 :(得分:2)

您可以使用此查询:

string query = "SELECT NULL AS EmptyColumn, * FROM [" + sheet + "$]";