将数据数组导出到Excel QueryTable

时间:2013-08-02 20:19:02

标签: c# export-to-excel

我成功将数据数组导出到Excel电子表格。现在,用户已经向我扔了一个曲线球,并希望它在Excel中的表中而不是仅仅是常规范围。我搜索过,我只能找到从外部数据源(SQL,文件等)创建查询表的方法。有没有办法将数组导出到查询表?下面是我用来创建和导出数组的代码。

 public class ExcelHelpers
    {



       /// <summary>
        /// Exports a list of objects to Excel. Objects go in the Rows while Object Properties go in the Columns
       /// </summary>
       /// <typeparam name="T"></typeparam>
        /// <param name="objects">List of objects to export.</param>
        /// <param name="filePath">Location to save file to. Does not need to exist</param>
        /// <param name="fileName">Name of excel file</param>
       public static void ExportToExcel<T>(IEnumerable<T> objects, string filePath, string fileName)
        {
            // Add \ to end of file name if it doesn't exist. Just want to be consistant
            if (!filePath.EndsWith(@"\"))          
                filePath += @"\";

            // Create directory if it doesn't exist
            if (!Directory.Exists(filePath))
                Directory.CreateDirectory(filePath);

            // Start Excel and get Application object. 
            Excel.Application excel = new Excel.Application();

            // Set it hidden and hide alerts
            excel.Visible = false;
            excel.DisplayAlerts = false;

            // Create a new workbook. 
            Excel.Workbook workbook = excel.Workbooks.Add();

            // Get the active sheet 
            Excel.Worksheet sheet = (Excel.Worksheet)workbook.ActiveSheet;

            try
            {
                // Convert the list into a rectangular array that Excel can read
                var data = GetObjectArray<T>(objects);

                // If at least one record got converted successfully
                if (data.Length > 1)
                {
                    // Get the range of cells that the data will go into. Size matches rectangular array size
                   string xlsRange = string.Format("A1:{0}{1}",                        
                       new object[] { GetExcelColumn(data.GetLength(1)), data.GetLength(0) });

                    // Insert data into the specified range of cells
                    Excel.Range range = sheet.get_Range(xlsRange);
                    range.Value = data;

                    // Auto-Fit the columns
                    range.EntireColumn.AutoFit();
                }

                // Save workbook
                workbook.SaveAs(
                    string.Format("{0}{1}", new object[] {filePath, fileName}),
                    Excel.XlFileFormat.xlWorkbookNormal);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                // Close
                sheet = null;
                workbook.Close();
                workbook = null;
                excel.Quit();
            }

            // Clean up 
            // NOTE: When in release mode, this does the trick 
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }

       /// <summary>
       /// Takes a List of objects objects and converts the objects and their properties into a rectangular array of objects
       /// </summary>
       /// <typeparam name="T"></typeparam>
       /// <param name="objects">List of objects to flatten</param>
       /// <returns>Rectangular array where objects are stored in [0] and properties are stored in [1]</returns>
       private static object[,] GetObjectArray<T>(IEnumerable<T> objects)
        {
            // Get list of object properties
            PropertyInfo[] properties = typeof(T).GetProperties();

            // Create rectangular array based on # of objects and # of object properties
            object[,] data = new object[objects.Count() + 1, properties.Length];

            // Loop through properties on object
            for (int j = 0; j < properties.Count(); j++)
            {
                // Write the property name into the first row of the array
                data[0, j] = properties[j].Name.Replace("_", " ");

                // Loop through objects and write out the specified property of each one into the array
                for (int i = 0; i < objects.Count(); i++)
                {
                    data[i + 1, j] = "'" + properties[j].GetValue(objects.ElementAt(i), null);
                }
            }

            // Return rectangular array
            return data;
        }

        /// <summary>
       /// Takes an Integer and converts it into Excel's column header code.
        /// </summary>
       /// <param name="colNumber">Number of Column in Excel. 1 = A</param>
       /// <returns>string that Excel can use</returns>
        private static string GetExcelColumn(int colNumber)
        {
            // If value is zero or less, return an empty string
            if (colNumber <= 0)
                return string.Empty;

            // If the value is less than or equal to 26 (Z), the column header
            // is only one character long. If it's greater, call this recursively
            // to get the first letter(s) of the column code.
            string first = (colNumber <= 26 ? string.Empty :
                GetExcelColumn((int)Math.Floor((colNumber - 1) / 26.00)));

            // Get the final letter in the column code
            int second = colNumber % 26;
            if (second == 0) second = 26;
            char finalLetter = (char)('A' + second - 1);            // Excel column header is the first part + the final character
            return string.Format("{0}{1}", new object[] { first, finalLetter });
        }
    }

1 个答案:

答案 0 :(得分:1)

您可以查找的对象类型是ListObject,代表Excel中使用的Table feature

以下代码将从您在一张表中的数据创建ListObject/Table(在此示例中,它创建的是A2单元格中的连续范围):

wbXLS.Worksheets[1].ListObjects.Add(Excel.XlListObjectSourceType.xlSrcRange, 
                 wbXLS.Worksheets[1].Range("A2").currentregion);

第二个参数决定考虑创建ListObject/Table的数据类型。