其他分享
首页 > 其他分享> > NPOI的使用(着重word文档的写入)

NPOI的使用(着重word文档的写入)

作者:互联网

之前用NPOI做word文档的导出,查询了大量资料,在此做一记录

不做过多讲解 直接上代码(word导出当中有一些业务处理,查看时自行甄别)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NPOI.HSSF.UserModel;
using NPOI.HPSF;
using NPOI.POIFS.FileSystem;
using System.IO;
using System.Reflection;
using NPOI.SS.UserModel;
using System.Data;
using NPOI.XSSF.UserModel;
using NPOI.XWPF.UserModel;
using Models;
using IBLL;
using Models.Common.Helpers;
using Models.Common;
using NPOI.OpenXmlFormats.Wordprocessing;
using System.Web.Caching;

namespace MOM.Helpers
{
    public class NPOIHelper
    {
        public NPOIHelper()
        {
        }

        private static HSSFWorkbook hssfworkbook;
        public static IOrgChkBLL OrgChkBLL { get; set; }
        public static IFileInfBLL FileInfBLL { get; set; }
        /// 初始化
        /// </summary>
        private static void InitializeWorkbook()
        {
            hssfworkbook = new HSSFWorkbook();
            DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
            dsi.Company = "";
            hssfworkbook.DocumentSummaryInformation = dsi;
            SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
            si.Subject = "";
            hssfworkbook.SummaryInformation = si;
        }

        /**//// <summary>

        /// DataTable写入Excel
        /// </summary>
        /// <param name="FileName">要保存的文件名称 eg:test.xls</param>
        /// <param name="SheetName">工作薄名称</param>
        /// <param name="dt">要写入的DataTable </param>
        public static void WriteToDownLoad(string FileName, string SheetName, DataTable dt, List<string> lstTitle)
        {

            string filename = FileName;
            HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
            //HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={}", filename));
            HttpContext.Current.Response.Clear();
            //初始化Excel信息
            InitializeWorkbook();
            //填充数据
            DTExcel(SheetName, dt, lstTitle);

            HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8).ToString());
            HttpContext.Current.Response.BinaryWrite(WriteToStream().GetBuffer());
            HttpContext.Current.Response.End();
        }

        /// <summary>
        /// lstTitle 设置表头
        /// </summary>
        /// List写入Excel
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <param name="FileName">要保存的文件名称 eg:test.xls</param>
        /// <param name="SheetName">工作薄名称</param>
        /// <param name="lst">要写入的List</param>
        public static void WriteToDownLoad<T>(string FileName, string SheetName, IList<T> lst, List<string> lstTitle)
        {
            string filename = FileName;
            HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
            // HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", FileName));
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8).ToString());

            //初始化Excel信息
            InitializeWorkbook();
            //填充数据
            ListExcel<T>(SheetName, lst, lstTitle);
            HttpContext.Current.Response.BinaryWrite(WriteToStream().GetBuffer());

            HttpContext.Current.Response.End();
        }

        private static MemoryStream WriteToStream()
        {
            MemoryStream file = new MemoryStream();
            hssfworkbook.Write(file);
            return file;
        }

        #region 数据填充部分

        /// 将DataTable数据写入到Excel
        /// </summary>
        /// <param name="SheetName"></param>
        /// <param name="dt"></param>
        /// <param name="lstTitle"></param>
        private static void DTExcel(string SheetName, DataTable dt, List<string> lstTitle)
        {
            ISheet sheet = hssfworkbook.CreateSheet(SheetName);
            int y = dt.Columns.Count;
            int x = dt.Rows.Count;
            //给定的标题为空,赋值datatable默认的列名
            if (lstTitle == null)
            {
                lstTitle = new List<string>();
                for (int ycount = 0; ycount < y; ycount++)
                {
                    lstTitle.Add(dt.Columns[ycount].ColumnName);
                }
            }
            IRow hsTitleRow = sheet.CreateRow(0);
            //标题赋值
            for (int yt = 0; yt < lstTitle.Count; yt++)
            {
                hsTitleRow.CreateCell(yt).SetCellValue(lstTitle[yt]);
            }
            //填充数据项
            for (int xcount = 1; xcount < x; xcount++)
            {
                IRow hsBodyRow = sheet.CreateRow(xcount);
                for (int ycBody = 0; ycBody < y; ycBody++)
                {
                    hsBodyRow.CreateCell(ycBody).SetCellValue(dt.DefaultView[xcount - 1][ycBody].ToString());
                }
            }
        }

        private static void ListExcel<T>(string SheetName, IList<T> lst, List<string> lstTitle)
        {
            ISheet sheet = hssfworkbook.CreateSheet(SheetName);
            T _t = (T)Activator.CreateInstance(typeof(T));
            PropertyInfo[] propertys = _t.GetType().GetProperties();
            //给定的标题为空,赋值T默认的列名
            if (lstTitle == null)
            {
                lstTitle = new List<string>();
                for (int ycount = 0; ycount < propertys.Length; ycount++)
                {
                    lstTitle.Add(((System.Reflection.MemberInfo)(propertys[ycount])).Name);//获取实体中列名称,去掉列类型
                }
            }
            IRow hsTitleRow = sheet.CreateRow(0);
            //获取title设置列
            int lstcount = lstTitle.Count();
            //标题赋值
            for (int yt = 0; yt < lstTitle.Count; yt++)
            {
                hsTitleRow.CreateCell(yt).SetCellValue(lstTitle[yt]);
            }
            //填充数据项
            for (int xcount = 0; xcount < lst.Count; xcount++)
            {
                IRow hsBodyRow = sheet.CreateRow(xcount + 1);
                for (int ycBody = 0; ycBody < lstcount; ycBody++)
                {
                    PropertyInfo pi = propertys[ycBody];
                    object obj = pi.GetValue(lst[xcount], null);
                    hsBodyRow.CreateCell(ycBody).SetCellValue(obj.ToString());
                }
            }
        }

        #endregion 数据填充部分

        /// <summary>
        /// 将Excel导入DataTable
        /// </summary>
        /// <param name="filepath">导入的文件路径(包括文件名)</param>
        /// <param name="sheetname">工作表名称</param>
        /// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
        /// <param name="numRow">从第几行开始导入</param>
        /// <returns>DataTable</returns>
        public static DataTable ExcelToDataTable(string filepath, Stream file, string sheetname, bool isFirstRowColumn, int numRow)
        {
            numRow = numRow < 1 ? 0 : numRow - 1;
            ISheet sheet = null;//工作表
            DataTable data = new DataTable();
            IWorkbook workbook = null;
            var startrow = 0;
            using (file)
            {
                try
                {
                    if (filepath.IndexOf(".xlsx") > 0) // 2007版本
                        workbook = new XSSFWorkbook(file);
                    else if (filepath.IndexOf(".xls") > 0) // 2003版本
                        workbook = new HSSFWorkbook(file);
                    if (sheetname != null)
                    {
                        sheet = workbook.GetSheet(sheetname);
                        if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
                        {
                            sheet = workbook.GetSheetAt(0);
                        }
                    }
                    else
                    {
                        sheet = workbook.GetSheetAt(0);
                    }
                    if (sheet != null)
                    {
                        IRow firstrow = sheet.GetRow(0);
                        int cellCount = firstrow.LastCellNum; //行最后一个cell的编号 即总的列数
                        if (isFirstRowColumn)
                        {
                            for (int i = firstrow.FirstCellNum; i < cellCount; i++)
                            {
                                NPOI.SS.UserModel.ICell cell = firstrow.GetCell(i);
                                if (cell != null)
                                {
                                    string cellvalue = cell.StringCellValue;
                                    if (cellvalue != null)
                                    {
                                        DataColumn column = new DataColumn(cellvalue);
                                        data.Columns.Add(column);
                                    }
                                }
                            }
                            startrow = sheet.FirstRowNum + numRow;
                        }
                        else
                        {
                            startrow = sheet.FirstRowNum + numRow;
                        }
                        //读数据行
                        int rowcount = sheet.LastRowNum;
                        for (int i = startrow; i <= rowcount; i++)
                        {
                            IRow row = sheet.GetRow(i);
                            if (row == null)
                            {
                                continue; //没有数据的行默认是null
                            }
                            DataRow datarow = data.NewRow();//具有相同架构的行
                            for (int j = row.FirstCellNum; j < cellCount; j++)
                            {
                                if (row.GetCell(j) != null)
                                {
                                    //如果是公式Cell 
                                    //则仅读取其Cell单元格的显示值 而不是读取公式
                                    if (row.GetCell(j).CellType == CellType.Formula)
                                    {
                                        row.GetCell(j).SetCellType(CellType.String);
                                        datarow[j] = row.GetCell(j).StringCellValue;
                                    }
                                    else
                                    {
                                        datarow[j] = row.GetCell(j).ToString();
                                    }
                                }
                            }
                            data.Rows.Add(datarow);
                        }
                    }
                    return data;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception: " + ex.Message);
                    return null;
                }
                finally { file.Close(); file.Dispose(); }
            }
        }

        /// <summary>
        /// 添加标题样式
        /// </summary>
        /// <param name="docxDocument"></param>
        /// <param name="strStyleId"></param>
        /// <param name="headingLevel"></param>
        private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel)
        {

            CT_Style ctStyle = new CT_Style();
            ctStyle.styleId = strStyleId;

            CT_String styleName = new CT_String();
            styleName.val = strStyleId;
            ctStyle.name = styleName;

            CT_DecimalNumber indentNumber = new CT_DecimalNumber();
            indentNumber.val = headingLevel.ToString();

            // lower number > style is more prominent in the formats bar
            ctStyle.uiPriority = indentNumber;

            CT_OnOff onoffnull = new CT_OnOff();
            ctStyle.unhideWhenUsed = onoffnull;

            // style shows up in the formats bar
            ctStyle.qFormat = onoffnull;

            // style defines a heading of the given level
            CT_PPr ppr = new CT_PPr();
            ppr.outlineLvl = indentNumber;
            ctStyle.pPr = ppr;

            XWPFStyle style = new XWPFStyle(ctStyle);

            // is a null op if already defined
            XWPFStyles styles = docxDocument.CreateStyles();

            style.StyleType = ST_StyleType.paragraph;
            styles.AddStyle(style);
        }
        /// <summary>
        /// word文档导出(包含业务代码,查看时需甄别)
        /// </summary>
        /// <param name="CpnID">企业代码</param>
        /// <param name="MdlID">模板代码</param>
        /// <param name="OrgID">机构代码</param>
        /// <param name="PstID1">岗位</param>
        /// <param name="ItemIDFat">父级事项代码</param>
        /// <param name="ItemIDs">事项代码</param>
        /// <param name="Sdt">开始日期</param>
        /// <param name="Edt">结束日期</param>
        /// <param name="prmFileInf"></param>
        /// <param name="IsExplain">是否包含说明</param>
        /// <param name="IsPicture">是否包含图片</param>
        /// <returns></returns>
        public static OperateReturnInfo CreateWordToOrgchkfl(string CpnID,string key, FileInfInfo prmFileInf,List<OrgChkDtlInfo> orgchkdtls)
        {
            CacheHelper.SetCache(key, 0, Cache.NoAbsoluteExpiration, new TimeSpan(1, 0, 0), CacheItemPriority.High);
            try
            {
                //循环层级,3-1对应1-3,根据层级计算缩进和字体大小
                int lvl = 3;// string.IsNullOrWhiteSpace(ItemIDFat) && string.IsNullOrWhiteSpace(ItemIDs) ? 3 : !string.IsNullOrWhiteSpace(ItemIDFat) && ItemIDFat.Length == 4 && string.IsNullOrWhiteSpace(ItemIDs) ? 2 : !string.IsNullOrWhiteSpace(ItemIDFat) && ItemIDFat.Length == 2 && string.IsNullOrWhiteSpace(ItemIDs) ? 3 : 1;
                if (lvl == 3)
                {
                    var dtls = orgchkdtls.GroupBy(x => x.firstItem).Select(y => new OrgChkDtlInfo { ItemID = y.Key.Substring(0, y.Key.IndexOf(' ')), ItemName = y.Key.Substring(y.Key.IndexOf(' ')) }).ToList();
                    var dtls1 = orgchkdtls.GroupBy(x => x.secondItem).Select(y => new OrgChkDtlInfo { ItemID = y.Key.Substring(0, y.Key.IndexOf(' ')), ItemName = y.Key.Substring(y.Key.IndexOf(' ')) }).ToList();
                    orgchkdtls.AddRange(dtls);
                    orgchkdtls.AddRange(dtls1);
                }
                if (lvl == 2)
                {
                    orgchkdtls.ToList().AddRange(orgchkdtls.GroupBy(x => x.secondItem).Select(y => new OrgChkDtlInfo { ItemID = y.Key.Substring(0, y.Key.IndexOf(' ')), ItemName = y.Key.Substring(y.Key.IndexOf(' ')) }));
                }
                orgchkdtls = orgchkdtls.OrderBy(x => x.ItemID).ToList();
                //创建document对象
                var doc = new XWPFDocument();
                addCustomHeadingStyle(doc, "Heading1", 1);
                //创建标题
                var ptit = doc.CreateParagraph();//段落
                ptit.Alignment = ParagraphAlignment.CENTER; //字体居中
                var t = ptit.StyleID;
                var runTitle = ptit.CreateRun();
                runTitle.SetText(prmFileInf.AttName.Substring(0, prmFileInf.AttName.LastIndexOf('.')));
                runTitle.FontSize = 18;
                runTitle.IsBold = true;
                runTitle.SetFontFamily("宋体", FontCharRange.None); //设置
                var itemids = orgchkdtls.GroupBy(x => new { x.ItemID, x.ItemName });
                int firindex = 0;
                int secindex = 0;
                int index = 0;
                int writeIndex = 0;
                foreach (var item in itemids)
                {
                    writeIndex++;
                    string nowspace = "";
                    string nowindex = string.Empty;
                    int FontSize = 10;
                    //根据层级产生编号,字体大小
                    if (item.Key.ItemID.Length == 2 && lvl == 3)
                    {
                        FontSize = 14;
                        firindex++;
                        nowindex = firindex.ToString();
                        secindex = 0;
                        index = 0;
                    }
                    else if (item.Key.ItemID.Length == 4)
                    {
                        if (lvl == 3)
                            nowspace = " ";
                        FontSize = 12;
                        secindex++;
                        nowindex = firindex + "-" + secindex;
                        index = 0;
                    }
                    else
                    {
                        index++;
                        FontSize = 10;
                        if (lvl == 3)
                        {
                            nowindex = firindex + "-" + secindex + "-" + index;
                            nowspace = "  ";
                        }
                        else if (lvl == 2)
                        {
                            nowindex = secindex + "-" + index;
                            nowspace = " ";
                        }
                        else
                            nowindex = index.ToString();
                        if (index > 1)//每个事项间隔一行空白
                        {
                            var ptit1 = doc.CreateParagraph();//段落
                            ptit1.Alignment = ParagraphAlignment.CENTER; //字体居中
                            var runTitle1 = ptit.CreateRun();
                            runTitle1.SetText("");
                        }
                    }
                    var p = doc.CreateParagraph();//事项段落
                    p.Alignment = ParagraphAlignment.LEFT;
                    var run = p.CreateRun();
                    if (item.Key.ItemID.Length < 6)
                        run.IsBold = true;
                    run.SetText(nowspace + nowindex + "、" + item.Key.ItemName);
                    run.FontSize = FontSize;
                    run.SetFontFamily("宋体", FontCharRange.CS); //设置字体
                    p.Style = "Heading1";
                    if (item.Key.ItemID.Length < 6)
                        continue;
                    foreach (var dtl in orgchkdtls.Where(x => x.ItemID == item.Key.ItemID))//添加事项下面所有图片和说明
                    {
                        var p1 = doc.CreateParagraph();
                        var run1 = p1.CreateRun();
                        run1.SetText(nowspace + dtl.ChrgName);
                        run1.FontSize = 8;
                        run1.SetColor("#959595");
                        run1.SetFontFamily("宋体", FontCharRange.None); //设置字体
                        if (!string.IsNullOrEmpty(dtl.FileName))
                        {
                            string[] files = dtl.FileName.Split(',');
                            for (int i = 0; i < files.Count(); i++)
                            {
                                string path = files[i].Substring(files[i].LastIndexOf('_') + 1);
                                string imgsavepath = MapPath("/Files/NPOI_" + path);
                                try
                                {
                                    S3Helper.DownloadS3File(CpnID + "/" + files[i].Substring(0, (files[i].LastIndexOf('_'))).Replace("_", "/"), files[i].Substring(files[i].LastIndexOf('_') + 1), imgsavepath);
                                    FileStream gfs = new FileStream(imgsavepath, FileMode.Open, FileAccess.Read);
                                    if (gfs != null)
                                    {
                                        var p2 = doc.CreateParagraph();
                                        var run2 = p2.CreateRun();
                                        run2.AddPicture(gfs, (int)NPOI.XWPF.UserModel.PictureType.JPEG, "1.jpg", 4500000, 3000000);
                                        if (i == (files.Count() - 1))
                                        {
                                            run2.AddCarriageReturn();
                                            run2.SetText(nowspace + dtl.UptDtt.ToString("MM月dd日") + " " + dtl.Brf);
                                            run2.SetTextPosition(10);
                                            run2.FontSize = 7;
                                            run2.SetFontFamily("宋体", FontCharRange.None); //设置字体
                                        }
                                        gfs.Close();
                                    }
                                    File.Delete(imgsavepath);
                                }
                                catch (Exception)
                                {
                                    var p2 = doc.CreateParagraph();
                                    var run2 = p2.CreateRun();
                                    if (i == (files.Count() - 1))
                                    {
                                        run2.AddCarriageReturn();
                                        run2.SetText(nowspace + dtl.UptDtt.ToString("MM月dd日") + " " + dtl.Brf);
                                        run2.SetTextPosition(10);
                                        run2.FontSize = 7;
                                        run2.SetFontFamily("宋体", FontCharRange.None); //设置字体
                                    }
                                }

                            }
                        }
                        else
                        {
                            var p2 = doc.CreateParagraph();
                            var run2 = p2.CreateRun();
                            run2.SetText(nowspace + dtl.UptDtt.ToString("MM月dd日") + " " + dtl.Brf);
                            run2.SetTextPosition(10);
                            run2.FontSize = 7;
                            run2.SetFontFamily("宋体", FontCharRange.None); //设置字体
                        }
                    }
                    var write = Math.Round((decimal)writeIndex / itemids.Count() * 100, 0);
                    CacheHelper.SetCache(key, write > 99 ? 99 : write, Cache.NoAbsoluteExpiration, new TimeSpan(1, 0, 0), CacheItemPriority.High);
                }
                //保存文档至S3
                FileStream os = new FileStream(MapPath("/Files/NPOI_" + prmFileInf.KeyVl + ".doc"), FileMode.OpenOrCreate);
                doc.Write(os);
                string filesavepath = MapPath("/Files/NPOI_" + prmFileInf.KeyVl + ".doc");
                FileStream fileStream = new FileStream(filesavepath, FileMode.Open, FileAccess.Read, FileShare.Read);
                // 读取文件的 byte[]
                byte[] bytes = new byte[fileStream.Length];
                fileStream.Read(bytes, 0, bytes.Length);
                fileStream.Close();
                // 把 byte[] 转换成 Stream
                Stream stream = new MemoryStream(bytes);
                var dt = DateTime.Now;
                string a = S3Helper.UploadToStream(CpnID + "/" + dt.Year + "/" + dt.Month + "/" + "Orgchkfl", Amazon.S3.S3CannedACL.Private, prmFileInf.KeyVl + ".doc", stream);
                prmFileInf.Attch = CpnID + "/" + dt.Year + "/" + dt.Month + "/" + "Orgchkfl/" + prmFileInf.KeyVl + ".doc";
                File.Delete(filesavepath);
                CacheHelper.SetCache(key, 100, Cache.NoAbsoluteExpiration, new TimeSpan(1, 0, 0), CacheItemPriority.High);
            }
            catch (Exception e)
            {
                CacheHelper.RemoveCache(key);
                foreach (string var in Directory.GetFiles(MapPath("/Files/")))
                {
                    if (var.IndexOf("NPOI_") > -1)
                        File.Delete(var);
                }
                return new OperateReturnInfo(OperateCode.Failed, "不合格典型案列生成失败!错误:" + e.Message);
            }
            FileInfBLL.SaveFileInf(prmFileInf);
            return new OperateReturnInfo(OperateCode.Success, "不合格典型案列生成成功!");
        }
        private static string MapPath(string strPath)
        {
            if (HttpContext.Current != null)
            {
                return MapPath(strPath);
            }
            else //非web程序引用 
            {
                strPath = strPath.Replace("/", "\\");
                if (strPath.StartsWith("\\"))
                {
                    //strPath = strPath.Substring(strPath.IndexOf('\\', 1)).TrimStart('\\'); 
                    strPath = strPath.TrimStart('\\');
                }
                return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
            }
        }
    }
}

标签:word,string,int,lstTitle,NPOI,文档,using,var,new
来源: https://www.cnblogs.com/luing-devil/p/14945849.html