步步为营-62-Excel的导入和导出

说明:NPOI组件的使用

1 添加引用

2 代码  

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CaterBLL;
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula;
using CaterModel;

namespace ExcelForm
{
    public partial class Form1 : Form
    {
        private ManagerInfoBLL bll = new ManagerInfoBLL();
       List<ManagerInfoModel> modelList = new List<ManagerInfoModel>( );

        public Form1()
        {
            InitializeComponent();
        }

        #region 01 窗体加载
        private void Form1_Load(object sender, EventArgs e)
        {
            modelList = bll.GetManaerList();
            dgvList.DataSource = bll.GetManaerList();
        } 
        #endregion

        #region 02 "导出" 按钮触发事件
        private void btnExcelOutPut_Click(object sender, EventArgs e)
        {
            //01 创建工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            //02 创建Sheet
            HSSFSheet sheet = workbook.CreateSheet("管理员信息");
            //03 创建行
            HSSFRow row = sheet.CreateRow(0);
            //04 创建单元格
            HSSFCell cell0 = row.CreateCell(0);
            //05 设置单元格的值
            cell0.SetCellValue("管理员列表");
            //06 合并单元格(开始行,开始列,结束行,结束列)
            sheet.AddMergedRegion(new NPOI.HSSF.Util.Region(0, 0, 0, 3));
            //07 设置字体居中
            HSSFCellStyle styleTitle = workbook.CreateCellStyle();
            styleTitle.Alignment = 2;//1左,2中,3右
            //08 将样式作用于单元格上
            cell0.CellStyle = styleTitle;
            //09 设置字体大小
            HSSFFont fontTitle = workbook.CreateFont();
            fontTitle.FontHeightInPoints = 14;
            styleTitle.SetFont(fontTitle);
            //10 创建标题行
            MakeTitleRow(sheet, styleTitle);

            //11 创建正文数据
            MakeContentRow(sheet);
            //12 保存工作表
            FileStream stream = new FileStream(@"E:1ManagerInfo.xls",FileMode.Create);
            workbook.Write(stream);
            stream.Close();
            stream.Dispose();
        }
        #endregion

        #region 03 创建标题行
        private void MakeTitleRow(HSSFSheet sheet, HSSFCellStyle styleTitle)
        {
           

           //01 创建行
            HSSFRow  rowTitle = sheet.CreateRow(1); 
            //02创建列
            HSSFCell cell0 = rowTitle.CreateCell(0);
            cell0.SetCellValue("编号");

            HSSFCell cell1 = rowTitle.CreateCell(1);
            cell1.SetCellValue("姓名");

            HSSFCell cell2 = rowTitle.CreateCell(2);
            cell2.SetCellValue("密码");

            HSSFCell cell3 = rowTitle.CreateCell(3);
            cell3.SetCellValue("类型");
            //03 将样式作用于单元格上
            cell0.CellStyle = styleTitle;
            cell1.CellStyle = styleTitle;
            cell2.CellStyle = styleTitle;
            cell3.CellStyle = styleTitle;
        }
        #endregion

        #region 04 创建内容行
        private void MakeContentRow(HSSFSheet sheet)
        {
            //01 指定行数
            int rowIndex = 2;
            foreach (var mi in modelList)
            {
                //02 创建行    
                HSSFRow rowContent = sheet.CreateRow(rowIndex++);
                //03 创建列
                HSSFCell cell0 = rowContent.CreateCell(0);
                cell0.SetCellValue(mi.MId);

                HSSFCell cell1 = rowContent.CreateCell(1);
                cell1.SetCellValue(mi.MName);

                HSSFCell cell2 = rowContent.CreateCell(2);
                cell2.SetCellValue(mi.MPwd);

                HSSFCell cell3 = rowContent.CreateCell(3);
                cell3.SetCellValue(mi.MType==1?"经理":"员工");
            }
        }

        #endregion

        #region 05 导入按钮触发事件
        private void btnExcelInput_Click(object sender, EventArgs e)
        {
            //01 定义list集合
            List<ManagerInfoModel> listManager = new List<ManagerInfoModel>( );
            //02 读取文件流 
            using (FileStream stream = new FileStream(@"E:1ManagerInfo.xls",FileMode.Open))
            {
                //02-01 创建workbook
                HSSFWorkbook workbook = new HSSFWorkbook(stream);
                //02-02 读取sheet
                HSSFSheet sheet = workbook.GetSheetAt(0);
                //02-03 读取数据 --跳过标题行
                int rowId = 2;
                while (sheet.GetRow(rowId) != null)
                {
                    HSSFRow row = sheet.GetRow(rowId);
                    //02-04 创建对象并实例化
                    ManagerInfoModel mi = new ManagerInfoModel();
                    mi.MId = (int)row.GetCell(0).NumericCellValue;
                    mi.MName = row.GetCell(1).StringCellValue;
                    mi.MPwd = row.GetCell(2).StringCellValue;
                    mi.MType = row.GetCell(2).StringCellValue == "经理" ? 1 : 0;
                    //02-05 将对象放入集合中
                    listManager.Add(mi);
                    rowId++;
                }

            }
            //指定为数据源
            dgvList.DataSource = listManager;
        }
        #endregion
    }
}
View Code

3 效果

二,导出设置样式

public static void ExportDQRoleDataNew2(DataTable dt, string fileName, string sheetName)
        {
            try
            {
                HSSFWorkbook wb = new HSSFWorkbook();//创建一个工作薄
                ISheet sheet = wb.CreateSheet(sheetName);//在工作薄中创建一个工作表 
                IRow rw = sheet.CreateRow(0);
                #region 设置样式
                //设置字体01 --开始
                //fontTitle :标题 fontHead :头部
                IFont fontTitle = wb.CreateFont();
                fontTitle.FontHeightInPoints = 14;
                fontTitle.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold;
                fontTitle.FontName = "微软雅黑";
                IFont fontHead = wb.CreateFont();
                fontHead.FontHeightInPoints = 11;
                fontHead.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold;
                fontHead.FontName = "微软雅黑";
                //设置字体01 --结束 

                //设置样式02 --开始
                //titleStyle:标题样式
                var titleStyle = wb.CreateCellStyle();
                //设置单元格上下左右边框线(不要边线)
                titleStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.None;
                titleStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.None;
                titleStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.None;
                titleStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.None;
                //文字水平和垂直对齐方式
                titleStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                titleStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
                //文字样式
                titleStyle.SetFont(fontTitle);

                var headStyle = wb.CreateCellStyle();
                //设置单元格上下左右边框线(不要边线)
                headStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.None;
                headStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.None;
                headStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.None;
                headStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.None;
                //文字水平和垂直对齐方式
                headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                headStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
                //文字样式
                headStyle.SetFont(fontHead);
                //设置背景色
                //s.FillForegroundColor = HSSFColor.Pink.Index
                headStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.CornflowerBlue.Index;
                headStyle.FillPattern = FillPattern.SolidForeground;

                var leftStyle = wb.CreateCellStyle();
                //设置单元格上下左右边框线(不要边线)
                leftStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.None;
                leftStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.None;
                leftStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.None;
                leftStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.None;
                //文字水平和垂直对齐方式
                leftStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                leftStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Justify;
                //文字样式
                leftStyle.SetFont(fontHead);
                //设置样式02 --结束 

                #endregion
                //循环一个表头来创建第一行的表头
                ICell ic = rw.CreateCell(0);
                ic.CellStyle = titleStyle;  //设置样式
                ic.SetCellValue(dt.Columns[0].ColumnName);
                //定义一个值,用于判断“所在部门”合并多少列
                int rowColIndex = 2;
                int rowColEnd = 2;
                Dictionary<int, int> rowColDic = new Dictionary<int, int>();
                string currentRoleCode = String.Empty;
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                  
                    DataRow dr = dt.Rows[i];
                    if (dr[0].ToString() == dr[1].ToString() && dr[1].ToString() == dr[2].ToString())
                    {
                        rowColEnd = i;
                        rowColDic.Add(rowColIndex, rowColEnd);
                        rowColIndex = i + 2;                      

                    }
                   
                    rw = sheet.CreateRow(i + 1);
                    rw.CreateCell(0).SetCellValue(dr[0].ToString());
                    rw.CreateCell(1).SetCellValue(dr[1].ToString());
                    rw.CreateCell(2).SetCellValue(dr[2].ToString());
                    rw.CreateCell(3).SetCellValue(dr[3].ToString());
                     
                }
                //CellRangeAddress四个参数为:起始行,结束行,起始列,结束列
                sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, 3));
                rowColDic.Remove(rowColDic.LastOrDefault().Key);
                foreach (KeyValuePair<int, int> kv in rowColDic)
                {
                    //CellRangeAddress四个参数为:起始行,结束行,起始列,结束列
                    sheet.AddMergedRegion(new CellRangeAddress(kv.Key, kv.Value, 0, 0));
                    //为空的数据设置背景色
                    IRow rwhead = sheet.GetRow(kv.Key-1);
                    rwhead.GetCell(0).CellStyle = headStyle;
                    rwhead.GetCell(1).CellStyle = headStyle;
                    rwhead.GetCell(2).CellStyle = headStyle;
                    rwhead.GetCell(3).CellStyle = headStyle;
                    //下一行的所在部门居中
                    IRow rwleft = sheet.GetRow(kv.Key);
                    rwleft.GetCell(0).CellStyle = leftStyle;
                }
               
                //设置单元格的宽度实际上是设置其所在列宽,所以要在单元格所在列上设置(列的设置在工作表上)
                sheet.SetColumnWidth(0, (int)22.13 * 256);
                sheet.SetColumnWidth(1, (int)49.88 * 256);
                sheet.SetColumnWidth(2, (int)13.50 * 256);
                sheet.SetColumnWidth(3, (int)14.88 * 256);
                MemoryStream file = new MemoryStream();
                wb.Write(file);
                string UserAgent = HttpContext.Current.Request.ServerVariables["http_user_agent"].ToLower();
                if (UserAgent.IndexOf("firefox") > 0)
                {
                    Encoding eGB3212 = Encoding.GetEncoding("GB2312");
                    fileName = eGB3212.GetString(eGB3212.GetBytes(fileName));
                }
                else
                {
                    fileName = HttpUtility.UrlEncode(fileName, Encoding.UTF8);
                }
                HttpContext.Current.Response.ContentType = "application/vnd.ms-excel;charset=UTF-8";
                HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}.xls", fileName));
                HttpContext.Current.Response.Clear();

                file.WriteTo(HttpContext.Current.Response.OutputStream);
            }
            catch (Exception ex)
            {
                throw new Exception("导出出错,请您联系系统管理员。" + ex.Message);
            }
        }
View Code

三,在原来的模板上导出

  /// <summary>
        /// NPOI使用ShiftRows向excel插入行,并复制原有样式
        /// </summary>
        /// <param name="file">模板文件,包含物理路径</param>
        /// <param name="dir">导出路径</param>
        public string ShiftRows(string file, string dir)
        {
            string errorType = "";
            string dqid = base.Request["OrgCode"];
            string orgLevel = Request.QueryString["OrgLevel"];
            //创建Excel文件的对象      
            FileStream fs = new FileStream(file, FileMode.Open);
            //如果是xls,使用HSSFWorkbook;如果是xlsx,使用XSSFWorkbook
            string extension = System.IO.Path.GetExtension(fldupload.FileName);
            IWorkbook workbook;
            ISheet sheet = null;
            if (extension == ".xls")
            {
                workbook = new HSSFWorkbook(fs);
            
                if (orgLevel == "10")
                {
                    sheet = (HSSFSheet)workbook.GetSheet("集团审批角色变更");
                }
                else if (orgLevel == "20")
                {
                    sheet = (HSSFSheet)workbook.GetSheet("区域公司审批角色变更");                
                }
            }
            else
            {
                workbook = new XSSFWorkbook(fs);
                if (orgLevel == "10")
                {
                    sheet = (XSSFSheet)workbook.GetSheet("集团审批角色变更");
                }
                else if (orgLevel == "20")
                {
                    sheet = (XSSFSheet)workbook.GetSheet("区域公司审批角色变更");
                }              
            }
            if (sheet==null)
            {
                errorType = "1";
                return errorType;
            }
            List<ICommonRoleOrgUserRelevance> list = BaseModelManager.CommonRoleOrgUserRelevanceDAO.RetrieveListByWhere(string.Format(" And OrgCode ='{0}' order by RoleCode", dqid));
            int rowCount = sheet.LastRowNum;
            int rowNullNum = rowCount; //记录一个空行,方便赋值空行的格式
            for (int i = 1; i <= rowCount; i++)
            {
                //获取当前行
                IRow currentRow = sheet.GetRow(i); //
                //通过正则表达式获取 角色编号
                //获取角色编码
                string role = currentRow.Cells[1] == null ? "" : currentRow.Cells[1].ToString().Trim();
                if (currentRow.Cells[1] == null || currentRow.Cells[1].ToString().Trim() == "")
                {
                    rowNullNum = i;
                }
                Regex regRole = new Regex(@"([^()]+)(?=))");
                string roleCode = "";
                MatchCollection mcRole = regRole.Matches(role);
                if (mcRole.Count > 0)
                {
                    roleCode = mcRole[mcRole.Count-1].Groups[1].Value;
                }

                if (!String.IsNullOrWhiteSpace(roleCode))
                {
                    //如果没有匹配到用户角色,那么遍历list,查看该角色下的所有用户
                    List<ICommonRoleOrgUserRelevance> listCurrentRoleContainsUsers = list.FindAll(c => c.RoleCode.Equals(roleCode));
                    string userInfo = String.Empty;
                    if (listCurrentRoleContainsUsers != null && listCurrentRoleContainsUsers.Count > 0)
                    {
                        //获取当前角色下的所有用户信息
                        int listCurrentRoleContainsUsersCount = listCurrentRoleContainsUsers.Count;
                        for (int j = 0; j < listCurrentRoleContainsUsersCount; j++)
                        {
                            if (j != listCurrentRoleContainsUsersCount - 1)
                            {
                                //如果不是最后一个
                                userInfo = userInfo + listCurrentRoleContainsUsers[j].UserName + "(" + listCurrentRoleContainsUsers[j].UserID + ");";
                            }
                            else
                            {
                                userInfo = userInfo + listCurrentRoleContainsUsers[j].UserName + "(" + listCurrentRoleContainsUsers[j].UserID + ")";
                            }
                        }
                        //最后把获取到的值赋给(原审批人和新审批人)
                        currentRow.Cells[2].SetCellValue(userInfo);
                        currentRow.Cells[3].SetCellValue(userInfo);
                        //为了统计数据库中有,但是,表单中没有的角色,所以list中的角色每使用一次,就删除掉,那么剩下的就是 数据库中>excel中的角色
                        list.RemoveAll(c => c.RoleCode.Equals(roleCode));
                    }
                }
            }
            //判断list中是否有剩余,那么剩下的就是 数据库中>excel中的角色
           
            if (list != null && list.Count > 0)
            {
                string currentRoleCode = string.Empty;
                string userInfo = string.Empty;
                //获取所有的角色名称
                List<ICommonRole> roleList = BaseModelManager.CommonRoleDAO.RetrieveListByWhere(String.Empty);//角色数据 
                
                foreach (ICommonRoleOrgUserRelevance entity in list)
                {
                    if (currentRoleCode != entity.RoleCode)
                    {
                        if (!String.IsNullOrWhiteSpace(currentRoleCode))
                        {
                            rowCount++;
                            //如果不等于空,说明有数据,有数据先保存一下
                            var rowSource = sheet.GetRow(rowNullNum);
                            var rowStyle = rowSource.RowStyle;//获取为空行的样式
                            var rowInsert = sheet.CreateRow(rowCount);
                            rowInsert.RowStyle = rowStyle;
                            rowInsert.Height = rowSource.Height;
                            for (int col = 0; col < rowSource.LastCellNum; col++)
                            {
                                var cellsource = rowSource.GetCell(col);
                                var cellInsert = rowInsert.CreateCell(col);
                                if (cellsource!=null)
                                {
                                    var cellStyle = cellsource.CellStyle;
                                    //设置单元格样式    
                                    if (cellStyle != null) {
                                        cellInsert.CellStyle = cellsource.CellStyle;
                                    }
                                }
                            }
                           ICommonRole entityRole= roleList.Find(c => c.RoleCode.Equals(currentRoleCode));
                           if (entityRole != null && !String.IsNullOrWhiteSpace(entityRole.RoleName))
                           {
                               rowInsert.Cells[2].SetCellValue(entityRole.RoleName + "(" + currentRoleCode + ")");
                           }
                           else {
                               rowInsert.Cells[2].SetCellValue(currentRoleCode);
                           }
                            rowInsert.Cells[3].SetCellValue(userInfo);
                            rowInsert.Cells[4].SetCellValue(userInfo);
                        }
                        currentRoleCode = entity.RoleCode;
                        userInfo = "";
                        userInfo = entity.UserName + "(" + entity.UserID + ")";
                    }
                    else
                    {
                        userInfo = userInfo + ";" + entity.UserName + "(" + entity.UserID + ")";
                    }
                }
            }

            using (MemoryStream ms = new MemoryStream())
            {
                if (workbook == null)
                    workbook.Write(ms);
                else
                    workbook.Write(ms);
                ms.Flush();
                ms.Position = 0;
                HttpContext curContext = HttpContext.Current;
                // 设置编码和附件格式
                curContext.Response.ContentType = "application/vnd.ms-excel";
                curContext.Response.ContentEncoding = Encoding.Default;
                curContext.Response.Charset = "";

                curContext.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(dir, Encoding.UTF8));
                curContext.Response.BinaryWrite(ms.GetBuffer());
                curContext.Response.End();
            }
            return errorType;
        }
View Code

 四,导出后火狐浏览器和其他浏览器关于文件名汉字乱码的问题

 using (MemoryStream ms = new MemoryStream())
            {
                if (workbook == null)
                {
                    workbook.Write(ms);
                }
                else
                {
                    workbook.Write(ms);
                }
                ms.Flush();
                ms.Position = 0;
                HttpContext curContext = HttpContext.Current;
                // 设置编码和附件格式
                curContext.Response.ContentType = "application/vnd.ms-excel";
                curContext.Response.ContentEncoding = Encoding.Default;
                curContext.Response.Charset = "";
                //这里判断使用的浏览器是否为Firefox,Firefox导出文件时不需要对文件名显示编码,编码后文件名会乱码
                //但是IE和Google需要编码才能保持文件名正常
                if (curContext.Request.ServerVariables["http_user_agent"].ToString().IndexOf("Firefox") != -1)
                {
                    curContext.Response.AddHeader("Content-Disposition", "attachment;filename="  + dir);
                }
                else
                {
                    curContext.Response.AddHeader("Content-Disposition", "attachment;filename="
                        + System.Web.HttpUtility.UrlEncode(dir, System.Text.Encoding.UTF8));
                }
                curContext.Response.BinaryWrite(ms.GetBuffer());
                curContext.Response.End();
            }
View Code

 五,导出后报Excel在“XXXX.xlsx”中发现不可读取的内容。是否恢复此工作簿的内容?如果信任此工作簿的来源,请单击“是”。Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃。

解决方法:在原来的基础上加“ curContext.Response.AddHeader("Content-Length", ms.Length.ToString());”

 using (MemoryStream ms = new MemoryStream())
            {
                if (workbook == null)
                {
                    workbook.Write(ms);
                }
                else
                {
                    workbook.Write(ms);
                }
                ms.Flush();
                ms.Position = 0;
                HttpContext curContext = HttpContext.Current;
                // 设置编码和附件格式
                curContext.Response.ContentType = "application/vnd.ms-excel";
                curContext.Response.ContentEncoding = Encoding.Default;
                curContext.Response.Charset = "";
                //这里判断使用的浏览器是否为Firefox,Firefox导出文件时不需要对文件名显示编码,编码后文件名会乱码
                //但是IE和Google需要编码才能保持文件名正常
                curContext.Response.AddHeader("Content-Length", ms.Length.ToString());//注意这里
                string fileName = sheet.SheetName + extension;
                if (curContext.Request.ServerVariables["http_user_agent"].ToString().IndexOf("Firefox") != -1)
                {
                    curContext.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
                }
                else
                {
                    curContext.Response.AddHeader("Content-Disposition", "attachment;filename="
                        + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
                }
                curContext.Response.BinaryWrite(ms.GetBuffer());
                curContext.Response.End();
            }
View Code
原文地址:https://www.cnblogs.com/YK2012/p/6890633.html