.NET Core使用NPOI导出复杂Word详解

前言:

  最近使用NPOI做了个导出Word文档的功能,关于使用.NET Core 导出Word文档的方式有很多。最终我为什么选择了NPOI来实现了这个功能,首先是NPOI是一个开源,免费且容易上手的第三方框架(并且现在已支持.NET Core,GitHub源码地址:https://github.com/tonyqus/npoi)。因为之前使用NPOI导出Execl比较多,这次第一次使用NPOI 来导出Word文档还真没有什么头绪。首先看了下GItHub中的源码有一个简单Word导出的示例,然后在看了网上有很多关于NPOI导出Word文档的案例,发现一个特点网上的好像都差不多,对于我而言网上的这些案例完全能够实现我的这个功能,但是感觉看了网上这些案例对NPOI实例化段落,表格和设置相关样式不太清楚(可能是因为自己笨),并且假如使用网上的方法来实现我的功能的话代码量会比较大,而且感觉代码非常的冗余(我是一个追求代码简洁的人,怎么能够容忍这样的事情发生呢!),因此通过查阅了一些资料和自己的理解,把关于使用NPOI导出Word时所要涉及的一些段落,表格样式做了相关注释,和把段落和表格的创建实例,设置文字、字体、对齐方式都封装了起了(为了少写代码),文章末尾会附上一个完整的案例下载地址。

一、首先引入NPOI NuGet:

版本说明:

  NPOI 2.4.1 (注意不同版本可能使用的姿势有点小差别)

程序包管理器控制台输入一下命令安装:

Install-Package NPOI -Version 2.4.1

通过NuGet管理解决方案安装:

二、导出的Work文档内容格式样式:

三、NPOI中的XWPFRun文本对象创建和属性简单概述:

XWPFRun文本对象说明:

  XWPFRun是段落的文本对象,先创建段落对象才能够在段落对象的基础上创建文本对象,并设置相关文本样式。

如下所示:

        /// <summary>
        /// 创建word文档中的段落对象和设置段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
        /// </summary>
        /// <param name="document">document文档对象</param>
        /// <param name="fillContent">段落第一个文本对象填充的内容</param>
        /// <param name="isBold">是否加粗</param>
        /// <param name="fontSize">字体大小</param>
        /// <param name="fontFamily">字体</param>
        /// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
        /// <returns></returns>
        private static XWPFParagraph ParagraphInstanceSetting(XWPFDocument document, string fillContent, bool isBold, int fontSize, string fontFamily, ParagraphAlignment paragraphAlign,)
        {
            XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
            paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)

            XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
            xwpfRun.IsBold = isBold;//文字加粗
            xwpfRun.SetText(fillContent);//填充内容
            xwpfRun.FontSize = fontSize;//设置文字大小
            xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
            return paragraph;
        }

XWPFRun文本对象的属性比较多,以下我简单说明常用的几种方式:

            XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象

            XWPFRun xwpfRun= paragraph.CreateRun();//创建段落文本对象
            xwpfRun.IsBold = isBold;//文字加粗
            xwpfRun.SetText(fillContent);//填充内容
            xwpfRun.FontSize = fontSize;//设置文字大小
            xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
            xwpfRun.SetColor("BED4F1");//设置字体颜色--十六进制
            xwpfRun.IsDoubleStrikeThrough=true;//是否显示双删除线
            xwpfRun.IsStrikeThrough = true;//是否显示单删除线
            xwpfRun.SetUnderline(UnderlinePatterns.Dash);//设置下划线,枚举类型
            xwpfRun.SetTextPosition(20);//设置文本位置(设置两行之间的行间)
            xwpfRun.AddBreak();//设置换行(</br>)
            xwpfRun.AddTab();//添加tab键
            xwpfRun.AddCarriageReturn();//添加回车键
            xwpfRun.IsImprinted = true;//印迹(悬浮阴影),效果和浮雕类似
            xwpfRun.IsItalic=true;//是否设置斜体(字体倾斜)
            xwpfRun.Subscript = VerticalAlign.SUBSCRIPT;//设置下标,枚举类型

NPOI中关于XWPFRun属性的更多使用技巧,请阅读源码:

源码地址:https://github.com/tonyqus/npoi/blob/master/ooxml/XWPF/Usermodel/XWPFRun.cs

四、NPOI生成Word完整代码:

using Microsoft.AspNetCore.Hosting;
using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.XWPF.UserModel;
using System;
using System.IO;

namespace Export.Services
{
    public class NpoiWordExportService
    {
        private static IHostingEnvironment _environment;

        public NpoiWordExportService(IHostingEnvironment iEnvironment)
        {
            _environment = iEnvironment;
        }

        #region 生成word

        /// <summary>
        ///  生成word文档,并保存静态资源文件夹(wwwroot)下的SaveWordFile文件夹中
        /// </summary>
        /// <param name="savePath">保存路径</param>
        public bool SaveWordFile(out string savePath)
        {
            savePath = "";
            try
            {
                string currentDate = DateTime.Now.ToString("yyyyMMdd");
                string checkTime = DateTime.Now.ToString("yyyy年MM月dd日");//检查时间
                //保存文件到静态资源wwwroot,使用绝对路径路径
                var uploadPath = _environment.WebRootPath + "/SaveWordFile/" + currentDate + "/";//>>>相当于HttpContext.Current.Server.MapPath("") 

                string workFileName = checkTime + "追逐时光企业员工培训考核统计记录表";
                string fileName = string.Format("{0}.docx", workFileName, System.Text.Encoding.UTF8);

                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }

                //通过使用文件流,创建文件流对象,向文件流中写入内容,并保存为Word文档格式
                using (var stream = new FileStream(Path.Combine(uploadPath, fileName), FileMode.Create, FileAccess.Write))
                {
                    //创建document文档对象对象实例
                    XWPFDocument document = new XWPFDocument();

                    /**
                     *这里我通过设置公共的Word文档中SetParagraph(段落)实例创建和段落样式格式设置,大大减少了代码的冗余,
                     * 避免每使用一个段落而去创建一次段落实例和设置段落的基本样式
                     *(如下,ParagraphInstanceSetting为段落实例创建和样式设置,后面索引表示为当前是第几行段落,索引从0开始)
                     */
                    //文本标题
                    document.SetParagraph(ParagraphInstanceSetting(document, workFileName, true, 19, "宋体", ParagraphAlignment.CENTER), 0);

                    //TODO:这里一行需要显示两个文本
                    document.SetParagraph(ParagraphInstanceSetting(document, $"编号:20190927101120445887", false, 14, "宋体", ParagraphAlignment.CENTER, true, $"    检查时间:{checkTime}"), 1);

                    document.SetParagraph(ParagraphInstanceSetting(document, "登记机关:企业员工监督检查机构", false, 14, "宋体", ParagraphAlignment.LEFT), 2);

                    #region 文档第一个表格对象实例
                    //创建文档中的表格对象实例
                    XWPFTable firstXwpfTable = document.CreateTable(4, 4);//显示的行列数rows:3行,cols:4列
                    firstXwpfTable.Width = 5200;//总宽度
                    firstXwpfTable.SetColumnWidth(0, 1300); /* 设置列宽 */
                    firstXwpfTable.SetColumnWidth(1, 1100); /* 设置列宽 */
                    firstXwpfTable.SetColumnWidth(2, 1400); /* 设置列宽 */
                    firstXwpfTable.SetColumnWidth(3, 1400); /* 设置列宽 */

                    //Table 表格第一行展示...后面的都是一样,只改变GetRow中的行数
                    firstXwpfTable.GetRow(0).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "企业名称", ParagraphAlignment.CENTER, 40, true));
                    firstXwpfTable.GetRow(0).GetCell(1).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "追逐时光", ParagraphAlignment.CENTER, 40, false));
                    firstXwpfTable.GetRow(0).GetCell(2).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "企业地址", ParagraphAlignment.CENTER, 40, true));
                    firstXwpfTable.GetRow(0).GetCell(3).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "湖南省-长沙市-岳麓区", ParagraphAlignment.CENTER, 40, false));

                    //Table 表格第二行
                    firstXwpfTable.GetRow(1).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "联系人", ParagraphAlignment.CENTER, 40, true));
                    firstXwpfTable.GetRow(1).GetCell(1).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "小明同学", ParagraphAlignment.CENTER, 40, false));
                    firstXwpfTable.GetRow(1).GetCell(2).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "联系方式", ParagraphAlignment.CENTER, 40, true));
                    firstXwpfTable.GetRow(1).GetCell(3).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "151****0456", ParagraphAlignment.CENTER, 40, false));

                    //Table 表格第三行
                    firstXwpfTable.GetRow(2).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "企业许可证号", ParagraphAlignment.CENTER, 40, true));
                    firstXwpfTable.GetRow(2).GetCell(1).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "XXXXX-66666666", ParagraphAlignment.CENTER, 40, false));
                    firstXwpfTable.GetRow(2).GetCell(2).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "检查次数", ParagraphAlignment.CENTER, 40, true));
                    firstXwpfTable.GetRow(2).GetCell(3).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, $"本年度检查8次", ParagraphAlignment.CENTER, 40, false));

                    firstXwpfTable.GetRow(3).MergeCells(0, 3);//合并3列
                    firstXwpfTable.GetRow(3).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "", ParagraphAlignment.LEFT, 10, false));

                    #endregion

                    var checkPeopleNum = 0;//检查人数
                    var totalScore = 0;//总得分

                    #region 文档第二个表格对象实例(遍历表格项)
                    //创建文档中的表格对象实例
                    XWPFTable secoedXwpfTable = document.CreateTable(5, 4);//显示的行列数rows:8行,cols:4列
                    secoedXwpfTable.Width = 5200;//总宽度
                    secoedXwpfTable.SetColumnWidth(0, 1300); /* 设置列宽 */
                    secoedXwpfTable.SetColumnWidth(1, 1100); /* 设置列宽 */
                    secoedXwpfTable.SetColumnWidth(2, 1400); /* 设置列宽 */
                    secoedXwpfTable.SetColumnWidth(3, 1400); /* 设置列宽 */

                    //遍历表格标题
                    secoedXwpfTable.GetRow(0).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "员工姓名", ParagraphAlignment.CENTER, 40, true));
                    secoedXwpfTable.GetRow(0).GetCell(1).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "性别", ParagraphAlignment.CENTER, 40, true));
                    secoedXwpfTable.GetRow(0).GetCell(2).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "年龄", ParagraphAlignment.CENTER, 40, true));
                    secoedXwpfTable.GetRow(0).GetCell(3).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "综合评分", ParagraphAlignment.CENTER, 40, true));

                    //遍历四条数据
                    for (var i = 1; i < 5; i++)
                    {
                        secoedXwpfTable.GetRow(i).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "小明" + i + "号", ParagraphAlignment.CENTER, 40, false));
                        secoedXwpfTable.GetRow(i).GetCell(1).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, "男", ParagraphAlignment.CENTER, 40, false));
                        secoedXwpfTable.GetRow(i).GetCell(2).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, 20 + i + "岁", ParagraphAlignment.CENTER, 40, false));
                        secoedXwpfTable.GetRow(i).GetCell(3).SetParagraph(SetTableParagraphInstanceSetting(document, firstXwpfTable, 90 + i + "分", ParagraphAlignment.CENTER, 40, false));

                        checkPeopleNum++;
                        totalScore += 90 + i;
                    }

                    #endregion

                    #region 文档第三个表格对象实例
                    //创建文档中的表格对象实例
                    XWPFTable thirdXwpfTable = document.CreateTable(5, 4);//显示的行列数rows:5行,cols:4列
                    thirdXwpfTable.Width = 5200;//总宽度
                    thirdXwpfTable.SetColumnWidth(0, 1300); /* 设置列宽 */
                    thirdXwpfTable.SetColumnWidth(1, 1100); /* 设置列宽 */
                    thirdXwpfTable.SetColumnWidth(2, 1400); /* 设置列宽 */
                    thirdXwpfTable.SetColumnWidth(3, 1400); /* 设置列宽 */
                    //Table 表格第一行,后面的合并3列(注意关于表格中行合并问题,先合并,后填充内容)
                    thirdXwpfTable.GetRow(0).MergeCells(0, 3);//从第一列起,合并3列
                    thirdXwpfTable.GetRow(0).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, thirdXwpfTable, "检查内容: " +
                        $"于{checkTime}下午检查了追逐时光企业员工培训考核并对员工的相关信息进行了相关统计,统计结果如下:                                                                                                                                                                                                                " +
                        "-------------------------------------------------------------------------------------" +
                        $"共对该企业({checkPeopleNum})人进行了培训考核,培训考核总得分为({totalScore})分。 " + "", ParagraphAlignment.LEFT, 30, false));

                    //Table 表格第二行
                    thirdXwpfTable.GetRow(1).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, thirdXwpfTable, "检查结果: ", ParagraphAlignment.CENTER, 40, true));
                    thirdXwpfTable.GetRow(1).MergeCells(1, 3);//从第二列起,合并三列
                    thirdXwpfTable.GetRow(1).GetCell(1).SetParagraph(SetTableParagraphInstanceSetting(document, thirdXwpfTable, "该企业非常优秀,坚持每天学习打卡,具有蓬勃向上的活力。", ParagraphAlignment.LEFT, 40, false));

                    //Table 表格第三行
                    thirdXwpfTable.GetRow(2).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, thirdXwpfTable, "处理结果: ", ParagraphAlignment.CENTER, 40, true));
                    thirdXwpfTable.GetRow(2).MergeCells(1, 3);
                    thirdXwpfTable.GetRow(2).GetCell(1).SetParagraph(SetTableParagraphInstanceSetting(document, thirdXwpfTable, "通过检查,评分为优秀!", ParagraphAlignment.LEFT, 40, false));

                    //Table 表格第四行,后面的合并3列(注意关于表格中行合并问题,先合并,后填充内容),额外说明
                    thirdXwpfTable.GetRow(3).MergeCells(0, 3);//合并3列
                    thirdXwpfTable.GetRow(3).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, thirdXwpfTable, "备注说明: 记住,坚持就是胜利,永远保持一种求知,好问的心理!", ParagraphAlignment.LEFT, 30, false));

                    //Table 表格第五行
                    thirdXwpfTable.GetRow(4).MergeCells(0, 1);
                    thirdXwpfTable.GetRow(4).GetCell(0).SetParagraph(SetTableParagraphInstanceSetting(document, thirdXwpfTable, "                                                                                                                                                                                                 检查人员签名:              年 月 日", ParagraphAlignment.LEFT, 40, false));
                    thirdXwpfTable.GetRow(4).MergeCells(1, 2);

                    thirdXwpfTable.GetRow(4).GetCell(1).SetParagraph(SetTableParagraphInstanceSetting(document, thirdXwpfTable, "                                                                                                                                                                                                 企业法人签名:              年 月 日", ParagraphAlignment.LEFT, 40, false));

                    #endregion

                    //向文档流中写入内容,生成word
                    document.Write(stream);

                    savePath = "/SaveWordFile/" + currentDate + "/" + fileName;

                    return true;
                }
            }
            catch (Exception ex)
            {
                //ignore
                savePath = ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 创建word文档中的段落对象和设置段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
        /// </summary>
        /// <param name="document">document文档对象</param>
        /// <param name="fillContent">段落第一个文本对象填充的内容</param>
        /// <param name="isBold">是否加粗</param>
        /// <param name="fontSize">字体大小</param>
        /// <param name="fontFamily">字体</param>
        /// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
        /// <param name="isStatement">是否在同一段落创建第二个文本对象(解决同一段落里面需要填充两个或者多个文本值的情况,多个文本需要自己拓展,现在最多支持两个)</param>
        /// <param name="secondFillContent">第二次声明的文本对象填充的内容,样式与第一次的一致</param>
        /// <returns></returns>
        private static XWPFParagraph ParagraphInstanceSetting(XWPFDocument document, string fillContent, bool isBold, int fontSize, string fontFamily, ParagraphAlignment paragraphAlign, bool isStatement = false, string secondFillContent = "")
        {
            XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
            paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)

            XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
            xwpfRun.IsBold = isBold;//文字加粗
            xwpfRun.SetText(fillContent);//填充内容
            xwpfRun.FontSize = fontSize;//设置文字大小
            xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定

            if (isStatement)
            {
                XWPFRun secondxwpfRun = paragraph.CreateRun();//创建段落文本对象
                secondxwpfRun.IsBold = isBold;//文字加粗
                secondxwpfRun.SetText(secondFillContent);//填充内容
                secondxwpfRun.FontSize = fontSize;//设置文字大小
                secondxwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
            }

            return paragraph;
        }

        /// <summary>
        /// 创建Word文档中表格段落实例和设置表格段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
        /// </summary>
        /// <param name="document">document文档对象</param>
        /// <param name="table">表格对象</param>
        /// <param name="fillContent">要填充的文字</param>
        /// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
        /// <param name="rowsHeight">设置文本位置(设置两行之间的行间),从而实现table的高度设置效果  </param>
        /// <param name="isBold">是否加粗(true加粗,false不加粗)</param>
        /// <param name="fontSize">字体大小</param>
        /// <returns></returns>
        private static XWPFParagraph SetTableParagraphInstanceSetting(XWPFDocument document, XWPFTable table, string fillContent, ParagraphAlignment paragraphAlign, int rowsHeight, bool isBold, int fontSize = 10)
        {
            var para = new CT_P();
            XWPFParagraph paragraph = new XWPFParagraph(para, table.Body);//创建表格中的段落对象
            paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)

            XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
            xwpfRun.SetText(fillContent);
            xwpfRun.FontSize = fontSize;//字体大小
            xwpfRun.IsBold = isBold;//是否加粗
            xwpfRun.SetFontFamily("宋体", FontCharRange.None);//设置字体(如:微软雅黑,华文楷体,宋体)
            xwpfRun.SetTextPosition(rowsHeight);//设置文本位置(设置两行之间的行间),从而实现table的高度设置效果
            return paragraph;
        }

        #endregion

    }
}

总结:

  写到最后我只想说我太难了,为了实现我想要的这个样式,通过不断的查阅资料,理解NPOI中的段落,文本基本属性。最终在我生成第22个word时,总算是达到了我要的效果。这里我将自己在网上查阅的一些资料和自己的实践心得分享给大家,希望能够帮到大家,别忘了给我star哟。

GitHub完整示例地址:https://github.com/YSGStudyHards/NPOI-Export-Word  

原文地址:https://www.cnblogs.com/Can-daydayup/p/11588531.html

时间: 2024-11-20 18:06:22

.NET Core使用NPOI导出复杂Word详解的相关文章

halcon导出类---HDevWindowStack详解

在HDevelop中编写好的程序在导出时,Halcon会帮我们转换成我们需要的语言,比如C++.例:HDevelop中有如下语句需要导出: dev_close_window() Halcon导出成C++语言就成了如下语句: if (HDevWindowStack::IsOpen()) close_window(HDevWindowStack::Pop()); 了解MFC的应该不难理解,这两句在底层做了什么!下面让我来讲解一下,呵呵 首先来看看HDevWindowStack这个类,其实这个类很简单

java实现excel的导入导出(poi详解)[转]

java实现excel的导入导出(poi详解) 博客分类: java技术 excel导出poijava 经过两天的研究,现在对excel导出有点心得了.我们使用的excel导出的jar包是poi这个阿帕奇公司的一个项目,后来被扩充了.是比较好用的excel导出工具. 下面来认识一下这个它吧. 我们知道要创建一张excel你得知道excel由什么组成,比如说sheet也就是一个工作表格,例如一行,一个单元格,单元格格式,单元格内容格式…这些都对应着poi里面的一个类. 一个excel表格: HSS

.net core 实现npoi导出

public void ExportDataToExcel() { var workbook = new HSSFWorkbook(); var sheet = workbook.CreateSheet("测试NPOI"); sheet.DefaultColumnWidth = 20; sheet.ForceFormulaRecalculation = true; var headFont = workbook.CreateFont(); headFont.IsBold = true;

EntityFramewok Core 1.1连接MSSql数据库详解

最近在研究ASP.NET Core,其中就用到了Entity Framework Core,对于Entity Framework Core连接SqlServer数据库,使用Code Frist创建数据库,更新数据库做一个记录. 开发工具:VS2017 RC Net Core版本:1.1 EF版本:1.1 一 创建项目 打开VS2017 RC,新建项目,选择ASP.NET Core Web应用程序,填写项目名称,解决方案名称,选择保存位置,下一步 然后选择ASP.NET Core 1.1,Web应

java实现excel的导入导出(poi详解)

经过两天的研究,现在对excel导出有点心得了.我们使用的excel导出的jar包是poi这个阿帕奇公司的一个项目,后来被扩充了.是比较好用的excel导出工具. 下面来认识一下这个它吧. 我们知道要创建一张excel你得知道excel由什么组成,比如说sheet也就是一个工作表格,例如一行,一个单元格,单元格格式,单元格内容格式…这些都对应着poi里面的一个类. 一个excel表格: HSSFWorkbook wb = new HSSFWorkbook(); 一个工作表格(sheet): HS

StreamSets学习系列之StreamSets的Core Tarball方式安装(图文详解)

不多说,直接上干货! 前期博客 核心安装包(Core Tarball) 该安装包包含核心的SDC软件,使该软件具有最小的软件连接器集合,当然你可以手动下载额外的节点(Stage) ①  通过Streamsets的UI进行安装,UI上点击的位置为:在该软件界面的右边(图标是一个礼物盒子...). ②  也可以通过使用CLI进行安装,安装过程如下所示: 第一步.下载该[核心安装包],比如版本为:streamsets-datacollector-core-3.3.0.tgz 第二步.解压该安装包 [[

DevExpress ASP.NET Core Controls v18.2新功能详解

行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍新版本新功能.本文将介绍了DevExpress ASP.NET Core Controls v18.2的新功能,新版30天免费试用!点击下载>> 全新的New ASP.NET Core Spreadsheet (CTP) 在新版本中,您可以非常轻松地将电子表格功能合并到任何ASP.NET Core应用程序中.新的Spreadsheet控件作为社区技术预览(CTP)提供

Asp.Net Core 中IdentityServer4 实战之 Claim详解

一.前言 由于疫情原因,让我开始了以博客的方式来学习和分享技术(持续分享的过程也是自己学习成长的过程),同时也让更多的初学者学习到相关知识,如果我的文章中有分析不到位的地方,还请大家多多指教:以后我会持续更新我的文章,望大家多多支持和关注. 上几篇文章主要分享了IdentityServer4在Asp.Net Core 3.x 中的应用,在上面的几篇分享中有一部分博友问了我这么一个问题"他通过IdentityServer4 来搭建授权中心网关服务,怎么才能在访问受保护的Api资源中获取到用户的相关

spark core源码分析15 Shuffle详解-写流程

博客地址: http://blog.csdn.net/yueqian_zhu/ Shuffle是一个比较复杂的过程,有必要详细剖析一下内部写的逻辑 ShuffleManager分为SortShuffleManager和HashShuffleManager 一.SortShuffleManager 每个ShuffleMapTask不会为每个Reducer生成一个单独的文件:相反,它会将所有的结果写到一个本地文件里,同时会生成一个index文件,Reducer可以通过这个index文件取得它需要处理