NPOI导出多个单子到一个Excel的多个工作簿里的问题

时间:2021-09-10 09:37:11
我要实现查询某天的单子,把改天的单子全部导出,每个单子导入一个工作簿中
NPOI导出多个单子到一个Excel的多个工作簿里的问题


问题出现了
NPOI导出多个单子到一个Excel的多个工作簿里的问题


代码:
 protected void btn_export_Click(object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty(TextBox1.Text.ToString()))
        {
            
            
            string SearchText = TextBox1.Text.ToString();
            SqlHelp sqly1 = new SqlHelp();
            string strfay1 = "select * from tOrderReview a where not exists(select 1 from tOrderReview where SerialNumber=a.SerialNumber and Record>a.Record) and aEffective='True' and 1=1 and SerialNumber like '%" + SearchText + "%' order by FillDate desc";
            //string strfay1 = "select * from tOrderProductInformation a where not exists(select 1 from tOrderProductInformation where SerialNumber=a.SerialNumber and Record>a.Record) and";
            DataTable dty1 = sqly1.GetDataTable(strfay1);
            sqly1.SqlClose();
            //string templetfilepath = Server.MapPath("template.xls");



            //string templetfilepath = @"E:\000\template.xls";
            string templetfilepath = Server.MapPath("template.xls"); 
            //string tpath = @"E:\000\out.xls";
            string tpath = Server.MapPath("out1.xls");
            FileInfo ff = new FileInfo(tpath);
            if (ff.Exists)
            {
                ff.Delete();
            }
            FileStream fs = File.Create(tpath);
            HSSFWorkbook x1 = new HSSFWorkbook();
            x1.Write(fs);
            fs.Close();


            FileStream fileRead = new FileStream(templetfilepath, FileMode.Open, FileAccess.Read);

            HSSFWorkbook hssfworkbook = new HSSFWorkbook(fileRead);

            FileStream fileSave2 = new FileStream(tpath, FileMode.Open, FileAccess.Read);
            HSSFWorkbook book2 = new HSSFWorkbook(fileSave2);
      
            HSSFSheet CPS = hssfworkbook.GetSheet("Sheet1") as HSSFSheet;
            for (int i = 1; i <= dty1.Rows.Count; i++)
            {
                CPS.CopyTo(book2, "Sheet" + i.ToString(), true, true);

                using (FileStream fileSave = new FileStream(tpath, FileMode.Open, FileAccess.Write))
                {
                    book2.Write(fileSave);
                }
            }


            int j = 1;

            foreach (DataRow dr in dty1.Rows)
            {

                SqlHelp sqlx1 = new SqlHelp();
                string strfax1 = "select * from tOrderProductInformation where SerialNumber='" + dr["SerialNumber"].ToString() + "' and Record='" + dr["Record"].ToString() + "' and bEffective='True'";

                DataTable dtx1 = sqlx1.GetDataTable(strfax1);
                sqlx1.SqlClose();
                // ToExcel(hssfworkbook,j, dr["OrderID"].ToString(), dr["SerialNumber"].ToString(), templetfilepath, dtx1, dr["CustomCode"].ToString());
                string OrderID = dr["OrderID"].ToString();
                string sns = dr["SerialNumber"].ToString();

                DataTable dt = dtx1;


                HSSFSheet ws = (HSSFSheet)book2.GetSheet("Sheet" + j.ToString());
                IRow mySourceStyleRow = ws.GetRow(10);//获取源格式行
                if (dt.Rows.Count >= 4)
                {
                    MyInsertRow(ws, 12, dt.Rows.Count - 3, mySourceStyleRow);//模版中已有3行,现在须调用函数插入DataTable行数-3行
                }
                //添加或修改WorkSheet里的数据 
                #region//给Excel单元格赋值
                SqlHelp sqlf = new SqlHelp();
                string strfacf = "select * from tOrderReview where OrderID='" + OrderID + "' and aEffective='True'";
                //string strfacf = "select * from tOrderReview a where not exists(select 1 from tOrderReview where SerialNumber=a.SerialNumber and Record>a.Record) and SerialNumber='" + lb_serialnum.Text.ToString() + "'";
                SqlDataReader drf = sqlf.ExecuteReader(strfacf);
                drf.Read();
                if (drf.HasRows)
                {
                    ws.GetRow(5).GetCell(15).SetCellValue(sns);
                    ws.GetRow(6).GetCell(2).SetCellValue(drf["CustomCode"].ToString());
                    ws.GetRow(6).GetCell(4).SetCellValue(drf["CustomName"].ToString());
                    ws.GetRow(6).GetCell(10).SetCellValue(drf["OrderSource"].ToString());
                    ws.GetRow(6).GetCell(15).SetCellValue(drf["OrderGrade"].ToString());
                    ws.GetRow(7).GetCell(2).SetCellValue(drf["SubmitDate"].ToString());
                    ws.GetRow(7).GetCell(4).SetCellValue(drf["DeliveryDate"].ToString());
                    ws.GetRow(7).GetCell(7).SetCellValue(drf["OrderSort"].ToString());
                }
                drf.Dispose();
                sqlf.SqlClose();
             
                if (dt.Rows.Count > 0)
                {
                    for (int n = 0; n < dt.Rows.Count; n++)
                    {
                        ws.GetRow(n + 10).GetCell(0).SetCellValue(n + 1);
                        ws.GetRow(n + 10).GetCell(1).SetCellValue(dt.Rows[n]["ProductCode"].ToString());
                        ws.GetRow(n + 10).GetCell(2).SetCellValue(dt.Rows[n]["ProductModel"].ToString());
                        ws.GetRow(n + 10).GetCell(3).SetCellValue(dt.Rows[n]["CustomVersion"].ToString());
                        ws.GetRow(n + 10).GetCell(4).SetCellValue(dt.Rows[n]["Amount"].ToString());
                    }
                }
                #endregion
                ws.ForceFormulaRecalculation = true;

                j++;
            }
            using (FileStream filess = File.OpenWrite(tpath))
            {
                book2.Write(filess);
            }
            //filess.Close();  
            System.IO.FileInfo filet = new System.IO.FileInfo(tpath);
            Response.Clear();
            Response.Charset = "GB2312";
            Response.ContentEncoding = System.Text.Encoding.UTF8;
            // 添加头信息,为"文件下载/另存为"对话框指定默认文件名   
            Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(SearchText + ".xls"));
            // 添加头信息,指定文件大小,让浏览器能够显示下载进度   
            Response.AddHeader("Content-Length", filet.Length.ToString());
            // 指定返回的是一个不能被客户端读取的流,必须被下载   
            Response.ContentType = "application/ms-excel";
            // 把文件流发送到客户端   
            Response.WriteFile(filet.FullName);
            // 停止页面的执行   

            Response.End();
        }
    }

    private void MyInsertRow(ISheet sheet, int insertrow, int insertcount, IRow ir)
    {
        #region 批量移动行
        sheet.ShiftRows(
            insertrow,                                 //--开始行
            sheet.LastRowNum,                      //--结束行
            insertcount,                             //--移动大小(行数)--往下移动
            true,                                  //是否复制行高
            false//,                               //是否重置行高
            //true                                 //是否移动批注
        );
        #endregion

        #region 对批量移动后空出的空行插,创建相应的行,并以插入行的上一行为格式源(即:插入行-1的那一行)
        for (int i = insertrow; i < insertrow + insertcount - 1; i++)
        {
            IRow targetRow = null;
            ICell sourceCell = null;
            ICell targetCell = null;

            targetRow = sheet.CreateRow(i + 1);

            for (int m = ir.FirstCellNum; m < ir.LastCellNum; m++)
            {
                sourceCell = ir.GetCell(m);
                if (sourceCell == null)
                    continue;
                targetCell = targetRow.CreateCell(m);

                //targetCell..Encoding = sourceCell.Encoding;
                targetCell.CellStyle = sourceCell.CellStyle;
                targetCell.SetCellType(sourceCell.CellType);
            }
            //CopyRow(sourceRow, targetRow);
            //Util.CopyRow(sheet, sourceRow, targetRow);
        }

        IRow firstTargetRow = sheet.GetRow(insertrow);
        ICell firstSourceCell = null;
        ICell firstTargetCell = null;

        for (int m = ir.FirstCellNum; m < ir.LastCellNum; m++)
        {
            firstSourceCell = ir.GetCell(m);
            if (firstSourceCell == null)
                continue;
            firstTargetCell = firstTargetRow.CreateCell(m);

            //firstTargetCell.Encoding = firstSourceCell.Encoding;
            firstTargetCell.CellStyle = firstSourceCell.CellStyle;
            firstTargetCell.SetCellType(firstSourceCell.CellType);
        }
        #endregion
    }


这个是根据我导出单个Excel文件改写出来的,本以为没什么问题,可是搞了一下午了,没法子,求了解这方面的牛人帮下忙,谢谢!200分送上!

6 个解决方案

#1


自己循环数据集,按单子分组,遍历,每个单子就创建一个sheet

#2


你是一开始循环就报错,还是循环几次后报错?

#3


引用 2 楼 starfd 的回复:
你是一开始循环就报错,还是循环几次后报错?

是在执行MyInsertRow(ISheet sheet, int insertrow, int insertcount, IRow ir)这个函数时出的问题,
因为我是用的Excel模版,中间的数据项数量是不定的,所以我需要根据数据项的数量来动态添加新的Excel行
上面这个函数就是用来在指定位置新增Excel行的
这个函数我在用Excel模版导出单个Excel(里面只有一个工作簿)时,是能正常运行的,不知道怎么到了这里就不行了

#4


问题找到了,我用的Excel模块,模版在该Excel的第一个工作簿Sheet1里
当有多个单子的时候,我就需要相应数量的工作簿来存放数据,就需要复制Sheet1来新增相应数量的工作簿
问题就出在这里:
FileStream fileRead = new FileStream(templetfilepath, FileMode.Open, FileAccess.Read);
 
            HSSFWorkbook hssfworkbook = new HSSFWorkbook(fileRead);
 
            FileStream fileSave2 = new FileStream(tpath, FileMode.Open, FileAccess.Read);
            HSSFWorkbook book2 = new HSSFWorkbook(fileSave2);
       
            HSSFSheet CPS = hssfworkbook.GetSheet("Sheet1") as HSSFSheet;
            for (int i = 1; i <= dty1.Rows.Count; i++)
            {
                CPS.CopyTo(book2, "Sheet" + i.ToString(), true, true);
 
                using (FileStream fileSave = new FileStream(tpath, FileMode.Open, FileAccess.Write))
                {
                    book2.Write(fileSave);
                }
            }

这个是我在官网文档里找到的方法,以Sheet1为基础复制新生成的工作簿,里面的格式都紊乱了,而且打开的时候,还会依次弹出以下警告:
NPOI导出多个单子到一个Excel的多个工作簿里的问题
NPOI导出多个单子到一个Excel的多个工作簿里的问题
NPOI导出多个单子到一个Excel的多个工作簿里的问题
NPOI导出多个单子到一个Excel的多个工作簿里的问题
打开复制新生成的Excel后,显示的格式紊乱:
模版 NPOI导出多个单子到一个Excel的多个工作簿里的问题

新生成的 NPOI导出多个单子到一个Excel的多个工作簿里的问题


当我把模版里的表格边框图片去掉后,复制新生成的Excel就是正常的了,再调用MyInsertRow(ISheet sheet, int insertrow, int insertcount, IRow ir)这个函数时也没出错了。一切都OK了,这还真是个奇怪的问题。 NPOI导出多个单子到一个Excel的多个工作簿里的问题NPOI导出多个单子到一个Excel的多个工作簿里的问题

#5


如果 在版权上没有什么要求,建议使用Aspose.Cell这东西好用。

#6


楼主搞定了嘛

#1


自己循环数据集,按单子分组,遍历,每个单子就创建一个sheet

#2


你是一开始循环就报错,还是循环几次后报错?

#3


引用 2 楼 starfd 的回复:
你是一开始循环就报错,还是循环几次后报错?

是在执行MyInsertRow(ISheet sheet, int insertrow, int insertcount, IRow ir)这个函数时出的问题,
因为我是用的Excel模版,中间的数据项数量是不定的,所以我需要根据数据项的数量来动态添加新的Excel行
上面这个函数就是用来在指定位置新增Excel行的
这个函数我在用Excel模版导出单个Excel(里面只有一个工作簿)时,是能正常运行的,不知道怎么到了这里就不行了

#4


问题找到了,我用的Excel模块,模版在该Excel的第一个工作簿Sheet1里
当有多个单子的时候,我就需要相应数量的工作簿来存放数据,就需要复制Sheet1来新增相应数量的工作簿
问题就出在这里:
FileStream fileRead = new FileStream(templetfilepath, FileMode.Open, FileAccess.Read);
 
            HSSFWorkbook hssfworkbook = new HSSFWorkbook(fileRead);
 
            FileStream fileSave2 = new FileStream(tpath, FileMode.Open, FileAccess.Read);
            HSSFWorkbook book2 = new HSSFWorkbook(fileSave2);
       
            HSSFSheet CPS = hssfworkbook.GetSheet("Sheet1") as HSSFSheet;
            for (int i = 1; i <= dty1.Rows.Count; i++)
            {
                CPS.CopyTo(book2, "Sheet" + i.ToString(), true, true);
 
                using (FileStream fileSave = new FileStream(tpath, FileMode.Open, FileAccess.Write))
                {
                    book2.Write(fileSave);
                }
            }

这个是我在官网文档里找到的方法,以Sheet1为基础复制新生成的工作簿,里面的格式都紊乱了,而且打开的时候,还会依次弹出以下警告:
NPOI导出多个单子到一个Excel的多个工作簿里的问题
NPOI导出多个单子到一个Excel的多个工作簿里的问题
NPOI导出多个单子到一个Excel的多个工作簿里的问题
NPOI导出多个单子到一个Excel的多个工作簿里的问题
打开复制新生成的Excel后,显示的格式紊乱:
模版 NPOI导出多个单子到一个Excel的多个工作簿里的问题

新生成的 NPOI导出多个单子到一个Excel的多个工作簿里的问题


当我把模版里的表格边框图片去掉后,复制新生成的Excel就是正常的了,再调用MyInsertRow(ISheet sheet, int insertrow, int insertcount, IRow ir)这个函数时也没出错了。一切都OK了,这还真是个奇怪的问题。 NPOI导出多个单子到一个Excel的多个工作簿里的问题NPOI导出多个单子到一个Excel的多个工作簿里的问题

#5


如果 在版权上没有什么要求,建议使用Aspose.Cell这东西好用。

#6


楼主搞定了嘛