npoi导出excel表

fantasykakaxi 2015-08-05 10:34:36
第一行标题行正常 后四行数据导出的是System.Web.UI.WebControls.GridViewRow
下面是代码 大神给解释下啊 要疯了

DataTable dt = new DataTable();
dt.Columns.Add("起始时间");
dt.Columns.Add("主办人");
dt.Columns.Add("事项部门");
dt.Columns.Add("事项类型");
dt.Columns.Add("事项说明");
dt.Columns.Add("联系信息");
dt.Columns.Add("联系人");
dt.Columns.Add("接收方式");
dt.Columns.Add("处理反馈");
dt.Columns.Add("完成时间");
dt.Columns.Add("用时");
dt.Columns.Add("补充");
dt.Columns.Add("更新时间");
dt.Columns.Add("更新人");
for (int i = 0; i < GridView1.Rows.Count; i++)
{
dt.Rows.Add(GridView1.Rows[i]);
}
NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("test_01");
NPOI.SS.UserModel.IRow row = sheet.CreateRow(0);
for (int i = 0; i < dt.Columns.Count; i++)
{
row.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
}

for (int i = 0; i < dt.Rows.Count; i++)
{
NPOI.SS.UserModel.IRow row2 = sheet.CreateRow(i + 1);
for (int j = 0; j < dt.Columns.Count; j++)
{
row2.CreateCell(j).SetCellValue(dt.Rows[i][j].ToString());
}
}
MemoryStream ms = new MemoryStream();
book.Write(ms);
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", DateTime.Now.ToString("yyyyMMddHHmmssfff")));
Response.BinaryWrite(ms.ToArray());
book = null;
ms.Close();
ms.Dispose();
...全文
225 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 5 楼 yangb0803 的回复:
参考下, 我用的是datatable 作为数据源的。 你可以將 datatable 改为 GridView1 试试。

        private bool exportexcelxlsx(string fname, DataTable tbl)
        {
            try
            {
                string fn = Path.GetFileNameWithoutExtension(fname);

                IWorkbook workbook = new XSSFWorkbook();
                ISheet worksheet = workbook.CreateSheet(fn);

                #region 右击文件 属性信息
                DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                dsi.Company = "test";

                SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                si.Author = uivariable.prms_user.u_name;          //填加xls文件作者信息
                si.ApplicationName = "test EXPORT";               //填加xls文件创建程序信息
                si.LastAuthor = uivariable.prms_user.u_name;      //填加xls文件最后保存者信息
                si.Comments = "test";                             //填加xls文件作者信息
                si.Title = "test EXPORT";                         //填加xls文件标题信息
                si.Subject = "test EXPORT";                       //填加文件主题信息
                si.CreateDateTime = System.DateTime.Now;
                #endregion

                XSSFCellStyle dateStyle = (XSSFCellStyle)workbook.CreateCellStyle();
                XSSFDataFormat format = (XSSFDataFormat)workbook.CreateDataFormat();
                dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");

                int row = tbl.Rows.Count;
                int col = tbl.Columns.Count;
                IRow rxls;
                ICell cell;
                string title = string.Empty;
                //表头
                int addrow = 0;                
                rxls = worksheet.CreateRow(addrow++);
                cell = rxls.CreateCell(0);
                cell.SetCellValue(title);

                rxls = worksheet.CreateRow(addrow++);
                cell = rxls.CreateCell(0);
                title = "Date : " + DateTime.Now.ToString("yyyy-MM-dd");
                cell.SetCellValue(title);

                //获取列名称
                for (int r = 0; r < col; r++)
                {
                    if (tbl.Columns[r].ColumnMapping != MappingType.Hidden)
                    {
                        cell = rxls.CreateCell(r);
                        string colname = tbl.Columns[r].ColumnName;
                        cell.SetCellValue(colname);
                    }
                }

                //写入数据
                string cellval = string.Empty;
                for (int i = 0; i < row; i++)
                {
                    rxls = worksheet.CreateRow(i + addrow);
                    for (int j = 0; j < col; j++)
                    {
                        if (tbl.Columns[j].ColumnMapping != MappingType.Hidden)
                        {
                            cell = rxls.CreateCell(j);
                            cellval = tbl.Rows[i][j].ToString();
                            cell.SetCellValue(cellval);
                        }
                    }
                }

                //页脚
                int ftr = col - 4;
                if (ftr < 0)
                {
                    ftr = 1;
                }

                addrow++;
                rxls = worksheet.CreateRow(row + addrow);
                cell = rxls.CreateCell(ftr);
                cellval = "导出日期: " + DateTime.Now.ToString();
                cell.SetCellValue(cellval);

                //转为字节数组  
                MemoryStream stream = new MemoryStream();
                workbook.Write(stream);
                var buf = stream.ToArray();

                //保存为Excel文件  
                using (FileStream fs = new FileStream(fname, FileMode.Create, FileAccess.Write))
                {
                    fs.Write(buf, 0, buf.Length);
                    fs.Flush();
                }

                string msg = "数据已经成功导出.\n\r" + fname;
                MessageBox.Show("数据已经成功导出");
                return true;
            }
            catch (Exception ex)
            {
                string msg = "数据导出失败." + ex.ToString();
                MessageBox.Show("数据导出失败");
                return false;
            }
        }

谢谢你 可是我还想用我那个
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 6 楼 Z65443344 的回复:
[quote=引用 4 楼 fantasykakaxi 的回复:] [quote=引用 3 楼 Z65443344 的回复:] 或者你完全不用DataTable把数据倒来倒去的 直接循环输出GridView1.Rows[i].Cell[j]不就得了
我也是 改改这 改改那 改错了 然后就乱了 [/quote] NPOI的代码没有问题 你现在主要的问题是GridView1放到DataTable里的代码不对,所以放进去的不是值,而是类型[/quote] 对对 应该是这样 可是我找不到在哪里改 你说的那个地方 我断点了 只发现在下标在动 没看到值得变化。。。
於黾 2015-08-05
  • 打赏
  • 举报
回复
引用 4 楼 fantasykakaxi 的回复:
[quote=引用 3 楼 Z65443344 的回复:] 或者你完全不用DataTable把数据倒来倒去的 直接循环输出GridView1.Rows[i].Cell[j]不就得了
我也是 改改这 改改那 改错了 然后就乱了 [/quote] NPOI的代码没有问题 你现在主要的问题是GridView1放到DataTable里的代码不对,所以放进去的不是值,而是类型
道玄希言 2015-08-05
  • 打赏
  • 举报
回复
参考下, 我用的是datatable 作为数据源的。 你可以將 datatable 改为 GridView1 试试。

        private bool exportexcelxlsx(string fname, DataTable tbl)
        {
            try
            {
                string fn = Path.GetFileNameWithoutExtension(fname);

                IWorkbook workbook = new XSSFWorkbook();
                ISheet worksheet = workbook.CreateSheet(fn);

                #region 右击文件 属性信息
                DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                dsi.Company = "test";

                SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                si.Author = uivariable.prms_user.u_name;          //填加xls文件作者信息
                si.ApplicationName = "test EXPORT";               //填加xls文件创建程序信息
                si.LastAuthor = uivariable.prms_user.u_name;      //填加xls文件最后保存者信息
                si.Comments = "test";                             //填加xls文件作者信息
                si.Title = "test EXPORT";                         //填加xls文件标题信息
                si.Subject = "test EXPORT";                       //填加文件主题信息
                si.CreateDateTime = System.DateTime.Now;
                #endregion

                XSSFCellStyle dateStyle = (XSSFCellStyle)workbook.CreateCellStyle();
                XSSFDataFormat format = (XSSFDataFormat)workbook.CreateDataFormat();
                dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");

                int row = tbl.Rows.Count;
                int col = tbl.Columns.Count;
                IRow rxls;
                ICell cell;
                string title = string.Empty;
                //表头
                int addrow = 0;                
                rxls = worksheet.CreateRow(addrow++);
                cell = rxls.CreateCell(0);
                cell.SetCellValue(title);

                rxls = worksheet.CreateRow(addrow++);
                cell = rxls.CreateCell(0);
                title = "Date : " + DateTime.Now.ToString("yyyy-MM-dd");
                cell.SetCellValue(title);

                //获取列名称
                for (int r = 0; r < col; r++)
                {
                    if (tbl.Columns[r].ColumnMapping != MappingType.Hidden)
                    {
                        cell = rxls.CreateCell(r);
                        string colname = tbl.Columns[r].ColumnName;
                        cell.SetCellValue(colname);
                    }
                }

                //写入数据
                string cellval = string.Empty;
                for (int i = 0; i < row; i++)
                {
                    rxls = worksheet.CreateRow(i + addrow);
                    for (int j = 0; j < col; j++)
                    {
                        if (tbl.Columns[j].ColumnMapping != MappingType.Hidden)
                        {
                            cell = rxls.CreateCell(j);
                            cellval = tbl.Rows[i][j].ToString();
                            cell.SetCellValue(cellval);
                        }
                    }
                }

                //页脚
                int ftr = col - 4;
                if (ftr < 0)
                {
                    ftr = 1;
                }

                addrow++;
                rxls = worksheet.CreateRow(row + addrow);
                cell = rxls.CreateCell(ftr);
                cellval = "导出日期: " + DateTime.Now.ToString();
                cell.SetCellValue(cellval);

                //转为字节数组  
                MemoryStream stream = new MemoryStream();
                workbook.Write(stream);
                var buf = stream.ToArray();

                //保存为Excel文件  
                using (FileStream fs = new FileStream(fname, FileMode.Create, FileAccess.Write))
                {
                    fs.Write(buf, 0, buf.Length);
                    fs.Flush();
                }

                string msg = "数据已经成功导出.\n\r" + fname;
                MessageBox.Show("数据已经成功导出");
                return true;
            }
            catch (Exception ex)
            {
                string msg = "数据导出失败." + ex.ToString();
                MessageBox.Show("数据导出失败");
                return false;
            }
        }

fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 3 楼 Z65443344 的回复:
或者你完全不用DataTable把数据倒来倒去的 直接循环输出GridView1.Rows[i].Cell[j]不就得了
我也是 改改这 改改那 改错了 然后就乱了
於黾 2015-08-05
  • 打赏
  • 举报
回复
或者你完全不用DataTable把数据倒来倒去的 直接循环输出GridView1.Rows[i].Cell[j]不就得了
於黾 2015-08-05
  • 打赏
  • 举报
回复
for (int i = 0; i < GridView1.Rows.Count; i++) { dt.Rows.Add(GridView1.Rows[i]); } 这个循环明显错了,不能这样add啊 循环行和列,一个单元格一个单元格赋值
於黾 2015-08-05
  • 打赏
  • 举报
回复
断点看dt.Rows[i][j].ToString()里是什么 估计你放进去的就是System.Web.UI.WebControls.GridViewRow
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
谢谢各位 尤其是红孩儿头像的那位哥
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 23 楼 yangb0803 的回复:

        for (int i = 0; i < GridView1.Rows.Count; i++)
        {
            NPOI.SS.UserModel.IRow row2 = sheet.CreateRow(i + 1);
            for (int j = 0; j < GridView1.Columns.Count; j++)
            {
                row2.CreateCell(j).SetCellValue(GridView1.Rows[i].Cells[j].ToString());
            }
        }
.....第二个循环写错了,sorry, 应该是取列
恩恩 解决了 哈哈 你的也给分
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 21 楼 Z65443344 的回复:
+2很正常啊 你dt里的第0列,对应的是表里的第2列(0和1都是编辑列) 所以 dt.Rows[0][0]=GridView1.Rows[0].Cells[2].Text; dt.Rows[0][1]=GridView1.Rows[0].Cells[3].Text; 写成循环不就是+2吗
对对对 我理解成excel里的+2了 想错了 嘿嘿
道玄希言 2015-08-05
  • 打赏
  • 举报
回复

        for (int i = 0; i < GridView1.Rows.Count; i++)
        {
            NPOI.SS.UserModel.IRow row2 = sheet.CreateRow(i + 1);
            for (int j = 0; j < GridView1.Columns.Count; j++)
            {
                row2.CreateCell(j).SetCellValue(GridView1.Rows[i].Cells[j].ToString());
            }
        }
.....第二个循环写错了,sorry, 应该是取列
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 20 楼 Z65443344 的回复:
for (int j = 0; j < GridView1.Rows.Count; j++) 内层变量写错了呗.应该按列数循环,而不是行数
是按照行循环吧 改成rows输出就不对了
於黾 2015-08-05
  • 打赏
  • 举报
回复
+2很正常啊 你dt里的第0列,对应的是表里的第2列(0和1都是编辑列) 所以 dt.Rows[0][0]=GridView1.Rows[0].Cells[2].Text; dt.Rows[0][1]=GridView1.Rows[0].Cells[3].Text; 写成循环不就是+2吗
於黾 2015-08-05
  • 打赏
  • 举报
回复
for (int j = 0; j < GridView1.Rows.Count; j++) 内层变量写错了呗.应该按列数循环,而不是行数
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 17 楼 Z65443344 的回复:
错了,是j+2,不是j-2 此外,你表里有多少列,dt里又是多少列,数量是一致的吗
+2对了 哈哈 谢谢 给分给分 dt里其实前两项是控件加编辑两个菜单 导致excel表中第一项其实是gridview中的第三项 但是小弟不明白 为毛是+2
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 15 楼 yangb0803 的回复:
数据不要转来转去了,直接GridView1取出来就用

        NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
        NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("test_01");
        NPOI.SS.UserModel.IRow row = sheet.CreateRow(0);
        row.CreateCell(0).SetCellValue("起始时间");
        row.CreateCell(1).SetCellValue("主办人");
        row.CreateCell(2).SetCellValue("事项部门");
        row.CreateCell(3).SetCellValue("事项类型");
        row.CreateCell(4).SetCellValue("事项说明");
        row.CreateCell(5).SetCellValue("联系信息");
        row.CreateCell(6).SetCellValue("联系人");
        row.CreateCell(7).SetCellValue("接收方式");
        row.CreateCell(8).SetCellValue("处理反馈");
        row.CreateCell(9).SetCellValue("完成时间");
        row.CreateCell(10).SetCellValue("用时");
        row.CreateCell(11).SetCellValue("补充");
        row.CreateCell(12).SetCellValue("更新时间");
        row.CreateCell(13).SetCellValue("更新人");


        for (int i = 0; i < GridView1.Rows.Count; i++)
        {
            NPOI.SS.UserModel.IRow row2 = sheet.CreateRow(i + 1);
            for (int j = 0; j < GridView1.Rows.Count; j++)
            {
                row2.CreateCell(j).SetCellValue(GridView1.Rows[i].Cells[j].ToString());
            }
        }

        MemoryStream ms = new MemoryStream();
        book.Write(ms);
        Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", DateTime.Now.ToString("yyyyMMddHHmmssfff")));
        Response.BinaryWrite(ms.ToArray());
        book = null;
        ms.Close();
        ms.Dispose();
这个只输出两行数据。。。其他不知道为啥没输出 不过思路很好
於黾 2015-08-05
  • 打赏
  • 举报
回复
错了,是j+2,不是j-2 此外,你表里有多少列,dt里又是多少列,数量是一致的吗
fantasykakaxi 2015-08-05
  • 打赏
  • 举报
回复
引用 14 楼 Z65443344 的回复:
那是因为你表里前两列是空值呗 for(int j=0;j<dt.Columns.Count;j++) { dr[j]=GridView1.Rows[i].Cells[j-2].ToString(); } 这样呢
这个试过 提示错误 指定的参数已超出有效值的范围
道玄希言 2015-08-05
  • 打赏
  • 举报
回复
数据不要转来转去了,直接GridView1取出来就用

        NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
        NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("test_01");
        NPOI.SS.UserModel.IRow row = sheet.CreateRow(0);
        row.CreateCell(0).SetCellValue("起始时间");
        row.CreateCell(1).SetCellValue("主办人");
        row.CreateCell(2).SetCellValue("事项部门");
        row.CreateCell(3).SetCellValue("事项类型");
        row.CreateCell(4).SetCellValue("事项说明");
        row.CreateCell(5).SetCellValue("联系信息");
        row.CreateCell(6).SetCellValue("联系人");
        row.CreateCell(7).SetCellValue("接收方式");
        row.CreateCell(8).SetCellValue("处理反馈");
        row.CreateCell(9).SetCellValue("完成时间");
        row.CreateCell(10).SetCellValue("用时");
        row.CreateCell(11).SetCellValue("补充");
        row.CreateCell(12).SetCellValue("更新时间");
        row.CreateCell(13).SetCellValue("更新人");


        for (int i = 0; i < GridView1.Rows.Count; i++)
        {
            NPOI.SS.UserModel.IRow row2 = sheet.CreateRow(i + 1);
            for (int j = 0; j < GridView1.Rows.Count; j++)
            {
                row2.CreateCell(j).SetCellValue(GridView1.Rows[i].Cells[j].ToString());
            }
        }

        MemoryStream ms = new MemoryStream();
        book.Write(ms);
        Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", DateTime.Now.ToString("yyyyMMddHHmmssfff")));
        Response.BinaryWrite(ms.ToArray());
        book = null;
        ms.Close();
        ms.Dispose();
加载更多回复(6)

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧