net Freamwork NPOI XWPF 根据模板导出到word 并动态加行

1 预览模板的准备  如图所示 我们需要导出此效果

2:替换/填充 资源  工作简历需要填充  基本信息需要替换占位符(一般对应数据库字段 好写代码)

c# 代码

 /// <summary>
        /// 根据数据源 生成word
        /// </summary>
        /// <returns></returns>
        public string GetWordForExport(参数)
        {
            var data = 根据参数获取数据库内容;

            if (data == null) throw new CustomException("没有可以导出的数据");           

           //工作简历
            var workHistory = data.MHBasicLevelCadreWorkHistory.OrderByDescending(t => t.StartDate).ToList();
           //读取word预览模板资源
            string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Export\\Template\\项目预览模板路径.docx";
            using (FileStream stream = File.OpenRead(filepath))
            {
                XWPFDocument doc = new XWPFDocument(stream);
                //遍历表格
                var tables = doc.Tables;
                var i=0;
                var j = 0;
                var k = 0;
                var m = 0;
                foreach (var table in tables)
                {
                    for (var index = 0; index < table.Rows.Count; index++)
                    {
                        //工作简历 填充资源   填充一行 数据库资源移出一行 这样不会重复
                        var row = table.Rows[index];
                        if (index >= 10 && index <= 16)
                        {
                            var w = workHistory.FirstOrDefault();
                            if(w==null) continue;

                            var cells = row.GetTableCells();

                            //没有样式的话 就直接设置内容
                            cells[0].SetText($"{w.StartDate:yyyy.MM}~{w.EndDate:yyyy.MM}");
                            cells[1].SetText(w.WorkUnit);
                            cells[2].SetText(w.Position);
                            cells[3].SetText(w.Witness);

                           //有样式的话 就用下面的代码 对单元格进行设置 字体什么的

                           //XWPFParagraph p1 = cells[0].AddParagraph();   //这样单元格里面内容会换行 如果不换行就直接 cells[0].Paragraphs[0];
                            //XWPFRun r1 = p1.CreateRun();
                            //r1.FontSize = 6;
                            //r1.SetText();
                            workHistory.Remove(w);
                        }

                       //替换占位符内容                     
                        else
                        {
                            foreach (var cell in row.GetTableCells())
                            {
                                foreach (var para in cell.Paragraphs)
                                {
                                    ReplaceKey(para, datac);
                                }
                            }
                        }
                        
                    }
                }

             // 3 保存资源 设置路径名 返回路径
                var filename = data.Name+ "的个人档案.docx";
                var savepath = AppDomain.CurrentDomain.BaseDirectory + "\\Export\\Temp\\" + filename;
                //为了表格复制和插入图片功能不冲突,先保存文档再读
                using (FileStream sw = File.Create(savepath))
                {
                    doc.Write(sw);
                }
                return "/Export/Temp/" + filename;
            }
        }

 

     //替换占位符   占位规则 按个人喜好 
        private void ReplaceKey(XWPFParagraph para, object data)
        {
            string text = para.ParagraphText;
            var reg = new Regex(@"\{\{.+?\}\}");
            var ms = reg.Matches(para.Text);
            if (ms.Count > 0)
            {
                Type t = data.GetType();
                PropertyInfo[] pi = t.GetProperties();
                foreach (PropertyInfo p in pi)
                {
                    if (text.Contains("{{" + p.Name + "}}"))
                    {
                        
                        var val = p.GetValue(data);
                        //性别处理下 汉字
                        if (p.Name == "Sex")
                        {
                            val = val.ToString() == "1" ? "男" : "女";
                        }
                         //图片
                        if (p.Name == "PicUrl")
                        {
                            //把值清掉 不然后面就替换一段url内容在word上 不需要 只需要放图片即可    
                            val = "";
                            var imgPath = HttpContext.Current.Server.MapPath("~/" + val);
                            if (!File.Exists(imgPath))
                            {
                                //换备用公共图片
                                imgPath = HttpContext.Current.Server.MapPath("~/Contents/images/noimg.png");
                            }
                            if (!File.Exists(imgPath))
                            {
                                //备用图片都没有 那就没添加图片操作了 空着内容
                            }
                            else
                            {
                                AddPicture(imgPath, para);
                            }
                                                  
                           
                            
                        }                    
                        if (val != null)
                        {
                            para.ReplaceText("{{" + p.Name + "}}", val.ToString());
                        }
                        else
                        {
                            para.ReplaceText("{{" + p.Name + "}}", "");
                        }
                    }
                }

            
            }
        }

 

 

//图片添加方法

  public void AddPicture(string picurl, XWPFParagraph paragraph)
        {


            if (!File.Exists(picurl)) { return; }
            var exname = Path.GetExtension(picurl)?.TrimStart('.').ToUpper();
            if (exname == "JPG") exname = "JPEG";
            if (!System.Enum.TryParse<NPOI.SS.UserModel.PictureType>(exname, out var pt))
            {
                pt = NPOI.SS.UserModel.PictureType.PNG;
            }
            XWPFParagraph par = paragraph;
            par.Alignment = ParagraphAlignment.CENTER;//居中
            XWPFRun run = par.CreateRun();
            //run.SetText("test");
            //var doc = paragraph.Document;


            using (FileStream fsImg = new FileStream(picurl, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {


                //var image = System.Drawing.Image.FromStream(fsImg, true);
                //var width = image.Width;
                //var height = image.Height;
                //if (width > 500)
                //{
                //    width = 500;
                //    height = 500 * image.Height / image.Width;
                //}
                //fsImg.Position = 0;


                var widthEmus = 80 * 9525; // (width * 9525);
                var heightEmus = 100 * 9525;//(height * 9525);

                run.AddPicture(fsImg, (int)pt, Guid.NewGuid().ToString() + "," + pt.ToString(), widthEmus, heightEmus);

                //CreatePicture(doc, run, picID, widthEmus, heightEmus);
            }

        }

 

 

 

如果还需要动态 加行 比如 工作经历不止模板7行 可能更多的话 

                var workHistoryBegin = 11;
                var workHistoryEnd = 18;

                //补行数 如果模板上的 行不够 需要动态加的话
                if (workHistory.Count() > 7)
                {
                    var addRows = workHistory.Count() - 7;                 

                    //开始补行数了
                    CT_Row ctrow = tables[0].Rows[workHistoryBegin+1].GetCTRow();  //找模板
                    //tables[0].RemoveRow(12); //先移除模板行
                    for (int index = workHistoryEnd+1; index < workHistoryEnd + 1 + addRows; index++)
                    {
                        CT_Row targetRow = new CT_Row();

                        //复制cell结构
                        foreach (CT_Tc item in ctrow.Items)
                        {
                            CT_Tc addTc = targetRow.AddNewTc();
                            addTc.tcPr = item.tcPr;//cell样式,只包括列宽和cell对齐方式

                            IList<CT_P> list_p = item.GetPList();

                            foreach (var p in list_p)
                            {
                                CT_P addP = addTc.AddNewP();
                                addP.pPr = p.pPr;//段落样式
                                IList<CT_R> list_r = p.GetRList();
                                foreach (CT_R r in list_r)
                                {
                                    CT_R addR = addP.AddNewR();
                                    addR.rPr = r.rPr;//run样式 包括字体等
                                    List<CT_Text> list_text = r.GetTList();
                                    foreach (CT_Text text in list_text)
                                    {
                                        CT_Text addText = addR.AddNewT();
                                        addText.space = text.space;
                                        addText.Value = text.Value;
                                    }
                                }
                            }
                        }
                        //增加数据行
                        XWPFTableRow mrow = new XWPFTableRow(targetRow, tables[0]);
                        tables[0].AddRow(mrow, index);

                    }

                   //吧结束行数更新下 供下面的去内容去开始使用
                    workHistoryEnd = 11 + workHistory.Count();

                }

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NPOI 是一个用于操作 Microsoft Office 格式文档的.NET 类库。通过 NPOI,我们可以使用 C# 代码来生成、读取和修改 Word、Excel 等文档。在 NPOI 中,我们可以使用模板来操作 Word 文档的导出。 使用 NPOI模板导出 Word,首先需要创建一个 Word 模板模板可以包含文本、图片、表格等要素,并且可以定义的样式和格式。在模板中,我们可以使用特定的标记或占位符来表示需要动态替换的部分。 接下来,在使用 NPOI 导出 Word 时,我们可以通过打开模板文件,并使用 NPOI 提供的方法和属性来操作 Word 文档的内容。我们可以根据需要选择要替换的标记或占位符,并将其替换为实际的数据或文本。可以使用 NPOI 设置文本样式、插入图片、创建表格以及设置表格样式等功能来完成模板导出。 在导出过程中,我们还可以根据需要进循环或条件判断,以动态生成多个重复的部分或根据特定条件添或删除某些内容。 导出完成后,我们可以将生成的 Word 文档保存到指定的位置或直接提供给用户下载。 总结来说,NPOI 提供了方便快捷的方法来按模板导出 Word 文档。通过使用模板,我们可以灵活生成各种不同的 Word 文档,满足不同的需求。同时,NPOI 还提供了对 Word 文档的其他操作,如读取、修改和删除等功能。这为开发人员提供了强大的功能,使其能够更好地操作和处理 Word 文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值