C#操作Excel文件

采用C#语言创建并填写Excel文件时出现异常来自 hresult 0x800a03ec的错误,网上资料多是说因为Excel的行索引或列索引出现0或者其他版本问题之类的(参考点击打开链接点击打开链接等),但是经过检查代码并参考如何在 Microsoft Visual C# .NET 中实现 Microsoft Excel 自动化如何使用 256 个以上的字段或列的数据导入 Excel资料,发现是因为03版和07版的Excel最大列数为256,最大行数为65536,如果超出这一限制,必然导致0X800a03ec的错误,所以对原有代码进行了改造,基本实现了所需功能。

此外还可以采用13版Excel,13版的.xlsx文档貌似没有行数和列数的限制。

附主要功能代码:


	/// <summary>
        /// Creates new Excel files for input data.
        /// </summary>
        /// <param name="desc">a list that stores the title of a table</param>
        /// <param name="dgs"></param>
        /// <param name="idx"></param>
        /// <param name="directory">the directory used for store the created files</param>
        private void newExcel(IList<Metadata> desc, IEnumerable<Data> dgs, int idx, string directory)
        {
            Application xlapp = new Application();
            Workbook wbook = null;
            int shtn = (int)Math.Ceiling(desc.Count / 256.0);
            int row = 9, part = 1;
            double ring = 0;
            double temp = double.NaN;
            foreach (var data in dgs)
            {
                double[] parsedata = parser.Parse(data.Datagram);
                ring = parsedata[idx];
                if (temp != ring)
                {
                    if (wbook != null)
                    {
                        break;
                        newExcelCore(ref wbook, directory, temp, part);
                    }
                    wbook = xlapp.Workbooks.Add(Missing.Value);
                    if (wbook.Sheets.Count < shtn)
                        wbook.Sheets.Add(Missing.Value, Missing.Value, shtn - wbook.Sheets.Count, XlSheetType.xlWorksheet);
                    newExcelTitle(ref wbook, desc);
                    row = 9;
                    temp = ring;
                }
                fillExcelData(ref wbook, 1, data.Time, row, parsedata, 0);
                row++;
                if (row > 65536)
                {
                    newExcelCore(ref wbook, directory, temp, part);
                    wbook = xlapp.Workbooks.Add(Missing.Value);
                    if (wbook.Sheets.Count < shtn)
                        wbook.Sheets.Add(Missing.Value, Missing.Value, shtn - wbook.Sheets.Count, XlSheetType.xlWorksheet);
                    newExcelTitle(ref wbook, desc);
                    row = 9;
                    part++;
                }//行数超出65536时,保存当前workbook,并创建新的workbook,其中part变量用作文件第几部分的标识。
            }
            if (wbook != null)
            {
                newExcelCore(ref wbook, directory, temp, part);
            }
            xlapp.Quit();
        }

        private void newExcelCore(ref Workbook wbook, string directory, double temp, int part)
        {
            string filename = string.Format(@"{0}\{2}_{1}_{3}.xlsx", directory, DateTime.Now.ToFileTime(), temp, part);
            wbook.SaveAs(filename);
            wbook.Close();
        }

        private void newExcelTitle(ref Workbook wbook, IList<Metadata> desc)
        {
            newExcelTitleCore(ref wbook, 1, desc, 0);
            
        }

        private void newExcelTitleCore(ref Workbook wbook, int sidx, IList<Metadata> desc, int startidx)
        {
            Worksheet wsheet = wbook.Worksheets[sidx];
            wsheet.Name = string.Format("Partition_{0}", sidx);
            fillExcelTitleCore(ref wsheet);
            for (int i = 2; i < (desc.Count - startidx + 2); i++)
            {
                if (i > 256)
                {
                    newExcelTitleCore(ref wbook, ++sidx, desc, i - 2);
                    break;
                }//列数大于256时,将剩下的数据递归写入新的Excel表单中。
                Metadata md = desc[startidx + i - 2];
                wsheet.Cells[1, i] = md.Addr;
                wsheet.Cells[2, i] = md.DataLoc;
                wsheet.Cells[3, i] = md.ValueType;
                wsheet.Cells[4, i] = md.DataLen;
                wsheet.Cells[5, i] = md.BitLoc;
                wsheet.Cells[6, i] = md.Range;
                wsheet.Cells[7, i] = md.Unit;
                wsheet.Cells[8, i] = md.Desc;
            }
        }

        private void fillExcelTitleCore(ref Worksheet wsheet)
        {
            wsheet.Cells[1, 1] = "PLC Address";
            wsheet.Cells[2, 1] = "Data Location";
            wsheet.Cells[3, 1] = "Value Type";
            wsheet.Cells[4, 1] = "Data Length";
            wsheet.Cells[5, 1] = "Bit Location";
            wsheet.Cells[6, 1] = "Data Range";
            wsheet.Cells[7, 1] = "Unit";
            wsheet.Cells[8, 1] = "Time";
        }

        private void fillExcelData(ref Workbook wbook,int sidx, DateTime dt, int row, double[] parsedata, int idx)
        {
            Worksheet wsheet = wbook.Sheets[sidx];
            double[] temp = null;
            int length = parsedata.Length - idx;
            if (length > 255)
            {
                fillExcelData(ref wbook, ++sidx, dt, row, parsedata, idx + 255);
                temp = new double[255];
            }
            else
            {
                temp = new double[length];
            }
            wsheet.Cells[row, 1] = dt;
            Array.Copy(parsedata, idx, temp, 0, temp.Length);
            wsheet.get_Range("B" + row, get_ColumnStr((uint)(temp.Length + 1)) + row).Value2 = temp;
        }


另外需要添加引用及Microsoft.Office.Interop.Excel名称空间。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值