精华内容
下载资源
问答
  • 1. 准备好.dotm模板文件,放入模板路径 C:\Users\AppData\Roaming\Microsoft\Templates(每个人电脑的路径可能不一样,大家用关键字搜索一下即可)2. 打开文档,“开发工具->文档模板”。选中准备好的.dotm...

    1. 准备好.dotm模板文件,放入模板路径 C:\Users\AppData\Roaming\Microsoft\Templates(每个人电脑的路径可能不一样,大家用关键字搜索一下即可)

    2. 打开文档,“开发工具->文档模板”。选中准备好的.dotm模板并“确定”。

    展开全文
  • 如何实现用户自定义Word模板

    千次阅读 2014-08-15 11:19:32
    但如果用户希望可以自己修改模板或自己定义新模板,并且又不需要开发人员针对新模板重写代码,那么应该使用怎样的技术来实现这种需求呢?本文就此问题展开论述。    在实际的开发过程中,针对导出生成word文档的...
    

    导读:  在涉及到word文档生成的项目中,一般采用编程将数据填充到word模板中生成文件的实现方式,如果模板由开发人员自己设计,那么编程填充数据是相对容易实现的;但如果用户希望可以自己修改模板或自己定义新模板,并且又不需要开发人员针对新模板重写代码,那么应该使用怎样的技术来实现这种需求呢?本文就此问题展开论述。

     

             在实际的开发过程中,针对导出生成word文档的需求,都是用程序填充数据到word模板中来实现的。所谓模板也就是标记了数据位置和字体段落样式的Word文件。一般来说,模板中的数据可以分为两种:一种是一对一的,一个数据在模版中对应一个数据位置,比如一个模板只需要使用“部门、姓名、原因、天数、日期”5个数据,每个数据只需要在文件中使用一次,如下图模板所示:

     


    用户定义模板时可以使用全部数据,也可以使用5个数据中的任意4个、3个甚至1个,但模板中数据标签的数量总是这个集合的子集。

     

             另一种是一对多,一个数据在同一个模版中可以使用一次,也可以使用多次。例如下图的介绍信的模板,每一个数据都需要在文件中出现两次。


     


    如果一个项目系统中所有的模板都是固定的,那么只需要在系统开发过程中由开发人员和用户一起把模板做好,之后,开发人员根据业务逻辑编写程序,给模板中的数据位置填充具体的数据即可实现,但在实际的应用中,很多时候不是这样的,最终用户还是希望能自己随时新建和修改模板,以满足不断变化的业务需求,如果每次模板的变化都需要和开发人员一起来完成,那么这个项目就永远不会完工。

             为了满足用户的这一需求,在项目中就需要提供一个模板制作和管理的模块,又为了让程序可以控制和识别用户定义模板中的数据位置,那么就需要开发人员来制作一个约定,让最终用户在新建或编辑模板时必须按照约定来制作模板。那么应该如何约定呢? PageOffice提供的解决方案就是使用书签和特殊格式的文本来对文档中需要插入数据的位置做标记。

            

    第一种方法使用书签来标记数据位置Word文档中插入书签的方法:把光标定位到需要标记数据位置的地方,点Word菜单中的“插入”-“书签”,就会弹出一个标题为“书签”的对话框,输入新书签的名称,书签名可以包含数字但中间不能有空格,用PageOffice开发的时候不推荐使用中文命名书签名。注意:如果新插入位置或新对象采用的是已有的书签名,原有的书签将自动取消,所以使用书签来标记数据位置的话,肯定是一个数据对应模板中一个位置的一对一模式。

    在使用PageOffice开发的过程中,为了避免出现与用户自己定义的书签出现冲突,要求插入的书签名称必须以“PO_”开头。注意是字母o,不是数字0。书签名是不区分大小写的也可以写成“po_”。在PageOffice的概念里提到的数据区域,本质上就是书签,但是只有“po_”开头的书签才叫数据区域(DataRegion),请大家注意这点。

     

    第二种方法就是使用特殊格式的文本来标记数据位置,比如说:【合同日期】、【##合同日期##】、[*合同日期*]……等等。使用书签标记数据位置有一个明显的缺点,同一个书签名称在一个word文档中只能出现一次,也就是说一个数据区域在文档中肯定是唯一的,但是很多时候模版中需要多处位置使用同样的数据变量,例如上面举例使用的“合同日期”可能就需要在一个合同中多个位置出现,使用数据区域肯定是无法满足需求的,但是使用特殊格式的文本来标记就没有这种限制了。

    在PageOffice的概念里,这种【合同日期】、【##合同日期##】、[*合同日期*]……等等特殊格式的文本都可以被认为是数据标签(DataTag),同一个数据标签可以在一份文件中多个位置出现多次,动态填充数据标签生成文件的时候,同一个数据标签都会被同样的数据替换。

    注意:【合同日期】和【##合同日期##】是两个不同的数据标签,同一个数据标签一定要是文本格式完全一致,比如:【##合同日期##】和【##合同日期##】虽然字体颜色和大小都不一样,但是文本内容是完全一样的,就被认为是同一个数据标签,所以在模版制作的时候定义数据标签是很简单的,只需要插入同样格式的文本就可以了。

     

    虽然以上的两点约定已经定好了,但是让用户在编辑模版的时候使用office自身的功能来制作和编辑模版,还是步骤繁琐、困难重重,制作的模板也容易出现一些问题,为此,PageOffice提供了定义模板的接口,由开发人员使用程序预先定义好用户可以使用的数据区域和数据标签,当用户编辑模版的时候,给用户弹出一个数据区域和数据标签的选择窗口,用户只需要选择使用这些数据区域和数据标签插入到word模版中,设置好数据的段落格式、字体、样式、颜色等等。这样以来,不但处理好了约定的问题,而且使得用户自定义模板的操作更加简单快捷。

     

    一、使用PageOffice提供的编辑模版功能:

             PageOffice给开发人员提供了定义模版的接口DefineDataRegionDefineDataTag方法,PageOffice.WordWriter.WordDocument.Template.DefineDataRegion

    PageOffice.WordWriter.WordDocument.Template.DefineDataTag

         1. 使用DefineDataRegion定义数据区域,例如ASP.NET代码如下:

           PageOffice.WordWriter.WordDocument doc =new

                               PageOffice.WordWriter.WordDocument();

           doc.Template.DefineDataRegion("Name","[姓名 ]");

           doc.Template.DefineDataRegion("Address","[地址 ]");

           doc.Template.DefineDataRegion("Tel","[电话 ]");

            doc.Template.DefineDataRegion("Phone","[手机 ]");

           doc.Template.DefineDataRegion("Sex","[性别 ]");

           doc.Template.DefineDataRegion("Age","[年龄 ]");

           doc.Template.DefineDataRegion("Email","[邮箱 ]");

           doc.Template.DefineDataRegion("QQNo","[ QQ]");

           doc.Template.DefineDataRegion("MSNNo","[ MSN]");

     

             或者用Java开发的话,代码如下:

           WordDocument doc = newWordDocument();

           doc.getTemplate().defineDataRegion("Name", "[姓名 ]");

           doc.getTemplate().defineDataRegion("Address", "[地址 ]");

           doc.getTemplate().defineDataRegion("Tel", "[电话 ]");

           doc.getTemplate().defineDataRegion("Phone", "[手机 ]");

           doc.getTemplate().defineDataRegion("Sex", "[性别 ]");

           doc.getTemplate().defineDataRegion("Age", "[年龄 ]");

           doc.getTemplate().defineDataRegion("Email", "[邮箱 ]");

           doc.getTemplate().defineDataRegion("QQNo", "[ QQ ]");

           doc.getTemplate().defineDataRegion("MSNNo", "[ MSN ]");

             开发人员用服务器端程序定义好用户可使用的数据区域,用户在客户端编辑模版的时候就可以使用这些数据区域。注意,这里的代码中不需要写PO_开头,PageOffice会自动添加这个前缀。用户编辑模版时看到的数据区域管理窗口,如下图所示:

     

     

     

             左侧“待添加数据区域”列表是可以用户目前可以使用的数据区域,右侧“已添加数据区域”列表是文档中已经添加的数据区域。此窗口的实现代码已经由PageOffice封装完毕,无需开发人员自己写复杂的js+html代码去实现,并且此窗口中内容的样式是可以修改的,如果对那些样式不太满意,只需要对此窗口html代码的样式做简单的调整即可。用户编辑数据区域时的效果,如下图所示:

            

     

        Word文档中已经添加过的数据区域都会出现在“已添加数据区域”的列表中,word文档中显示的是DefineDataRegion方法第二个参数的值。这些插入到模版中的数据区域就如方法一中手动插入的书签完全一样,也是带PO_开头的书签。使用此方法就可以实现用户自定义模版的功能,开发人员只管编写程序给数据区域赋值对应的数据,用户自己定义模版的样式、数据位置和数据的多少,用户可以使用全部的数据区域,也可以只使用部分, PageOffice在生成文件的时候,会自动忽略没有使用的数据区域,而不需要开发人员做任何代码的调整。

     

     



      2. 使用DefineDataTag定义数据标签,例如ASP.NET的代码如下:

            PageOffice.WordWriter.WordDocument doc =new

                            PageOffice.WordWriter.WordDocument();

           doc.Template.DefineDataTag("{甲方 }");

           doc.Template.DefineDataTag("{乙方 }");

           doc.Template.DefineDataTag("{担保人 }");

           doc.Template.DefineDataTag("合同日期");

           doc.Template.DefineDataTag("合同编号");

             或者用Java开发的代码如下:

                       WordDocument doc = newWordDocument();

             doc.getTemplate().defineDataTag("{甲方}");

                       doc.getTemplate().defineDataTag("{乙方}");

                       doc.getTemplate().defineDataTag("{担保人 }");

                       doc.getTemplate().defineDataTag("合同日期");

                       doc.getTemplate().defineDataTag("合同编号");

             开发人员用服务器端程序定义好用户可使用的数据标签,用户在客户端编辑模版的时候就可以使用这些数据标签。用户编辑模版时看到的数据标签管理窗口,如下图所示:

            

     

    同数据区域一样,对此窗口的实现代码,PageOffice也已经封装完毕,无需开发人员自己写复杂的js+html代码去实现,并且此窗口中内容的样式是可以修改的,如果对那些样式不太满意,只需要简单的调整一下此窗口html代码中的样式即可。开发人员只管编写程序给数据标签赋值对应的数据,用户自己定义模版的样式、数据位置和数据的多少,用户可以使用全部的数据区域,也可以只使用部分, PageOffice在生成文件的时候,会自动忽略没有使用的数据标签,而不需要开发人员做任何代码的调整。

    与数据区域的管理不同的是,由于数据标签在文件中不是唯一的,所以不管在文件中添加了多少个数据标签,在数据标签管理窗口中的数据标签都是不会减少的。

     

    二、使用PageOffice.WordWriter命名空间中的对象填充数据到Word模版,动态生成文档:

     

    .WordDocument.OpenDataRegion 方法

    .WordDocument.OpenDataTag 方法

     

    开发人员只需要使用上面的两个方法,针对word模版编写程序,给所有的数据区域和数据标签赋值相应的数据即可,无需关心模版中到底使用了多少个数据区域和数据标签,那些Word模版中从来没有使用过的数据区域和数据标签,PageOffice会自动忽略,而无需开发人员做任何代码的修改,从而完美实现用户自定义模板的需求。

    ASP.NET开发的赋值代码如下,

     

            PageOffice.WordWriter.WordDocument doc =new  

                                 PageOffice.WordWriter.WordDocument();

           doc.OpenDataRegion("Name").Value="张三";       

           doc.OpenDataRegion("Age").Value="21";

          ……

           doc.OpenDataTag("{甲方公司名称 }").Value ="微软中国总部";

           doc.OpenDataTag("{乙方公司名称 }").Value ="北京幻想科技公司";

          ……

       PageOfficeCtrl1.SetWriter(doc);

     

    Java开发的赋值代码如下:

     

             WordDocument doc = new WordDocument();

           doc.openDataRegion("Name").setValue("张三");       

           doc.openDataRegion("Age").setValue("21"); 

            ……

            doc.openDataTag("{甲方公司名称 }").setValue("微软中国总部");

            doc.openDataTag("{乙方公司名称 }").setValue( "北京幻想科技公司");

            ……

            poCtrl.setWriter(doc);

     

             详细请参考PageOffice示例代码Samples中“综合演示”目录下的示例TemplateEdit.rar的运行效果。或者从下面的链接下载单独的TemplateEdit.rar示例:

             ASP.NEThttp://www.zhuozhengsoft.com/smalldemo/TemplateEdit_ASP.NET.rar

             Javahttp://www.zhuozhengsoft.com/smalldemo/TemplateEdit_java.rar

    展开全文
  • PageOffice--实现用户自定义Word模板

    千次阅读 2018-09-12 14:19:50
    但如果用户希望可以自己修改模板或自己定义新模板,并且又不需要开发人员针对新模板重写代码,那么应该使用怎样的技术来实现这种需求呢?本文就此问题展开论述。 在实际的开发过程中,针对导出生成word文档的需求...

    导读: 在涉及到word文档生成的项目中,一般采用编程将数据填充到word模板中生成文件的实现方式,如果模板由开发人员自己设计,那么编程填充数据是相对容易实现的;但如果用户希望可以自己修改模板或自己定义新模板,并且又不需要开发人员针对新模板重写代码,那么应该使用怎样的技术来实现这种需求呢?本文就此问题展开论述。

    在实际的开发过程中,针对导出生成word文档的需求,都是用程序填充数据到word模板中来实现的。所谓模板也就是标记了数据位置和字体段落样式的Word文件。一般来说,模板中的数据可以分为两种:一种是一对一的,一个数据在模版中对应一个数据位置,比如一个模板只需要使用“部门、姓名、原因、天数、日期”5个数据,每个数据只需要在文件中使用一次,如下图模板所示:

    1710

    用户定义模板时可以使用全部数据,也可以使用5个数据中的任意4个、3个甚至1个,但模板中数据标签的数量总是这个集合的子集。

    另一种是一对多,一个数据在同一个模版中可以使用一次,也可以使用多次。例如下图的介绍信的模板,每一个数据都需要在文件中出现两次。

    1711

    如果一个项目系统中所有的模板都是固定的,那么只需要在系统开发过程中由开发人员和用户一起把模板做好,之后,开发人员根据业务逻辑编写程序,给模板中的数据位置填充具体的数据即可实现,但在实际的应用中,很多时候不是这样的,最终用户还是希望能自己随时新建和修改模板,以满足不断变化的业务需求,如果每次模板的变化都需要和开发人员一起来完成,那么这个项目就永远不会完工。
    为了满足用户的这一需求,在项目中就需要提供一个模板制作和管理的模块,又为了让程序可以控制和识别用户定义模板中的数据位置,那么就需要开发人员来制作一个约定,让最终用户在新建或编辑模板时必须按照约定来制作模板。那么应该如何约定呢? PageOffice提供的解决方案就是使用书签和特殊格式的文本来对文档中需要插入数据的位置做标记。

    第一种方法使用书签来标记数据位置。Word文档中插入书签的方法:把光标定位到需要标记数据位置的地方,点Word菜单中的“插入”-“书签”,就会弹出一个标题为“书签”的对话框,输入新书签的名称,书签名可以包含数字但中间不能有空格,用PageOffice开发的时候不推荐使用中文命名书签名。注意:如果新插入位置或新对象采用的是已有的书签名,原有的书签将自动取消,所以使用书签来标记数据位置的话,肯定是一个数据对应模板中一个位置的一对一模式。
    在使用PageOffice开发的过程中,为了避免出现与用户自己定义的书签出现冲突,要求插入的书签名称必须以“PO_”开头。注意是字母o,不是数字0。书签名是不区分大小写的也可以写成“po_”。在PageOffice的概念里提到的数据区域,本质上就是书签,但是只有“po_”开头的书签才叫数据区域(DataRegion),请大家注意这点。

    第二种方法就是使用特殊格式的文本来标记数据位置,比如说:【合同日期】、【##合同日期##】、[合同日期]……等等。使用书签标记数据位置有一个明显的缺点,同一个书签名称在一个word文档中只能出现一次,也就是说一个数据区域在文档中肯定是唯一的,但是很多时候模版中需要多处位置使用同样的数据变量,例如上面举例使用的“合同日期”可能就需要在一个合同中多个位置出现,使用数据区域肯定是无法满足需求的,但是使用特殊格式的文本来标记就没有这种限制了。

    在PageOffice的概念里,这种【合同日期】、【##合同日期##】、[合同日期]……等等特殊格式的文本都可以被认为是数据标签(DataTag),同一个数据标签可以在一份文件中多个位置出现多次,动态填充数据标签生成文件的时候,同一个数据标签都会被同样的数据替换。

    注意:【合同日期】和【##合同日期##】是两个不同的数据标签,同一个数据标签一定要是文本格式完全一致,比如:【##合同日期##】和【##合同日期##】虽然字体颜色和大小都不一样,但是文本内容是完全一样的,就被认为是同一个数据标签,所以在模版制作的时候定义数据标签是很简单的,只需要插入同样格式的文本就可以了。

    虽然以上的两点约定已经定好了,但是让用户在编辑模版的时候使用office自身的功能来制作和编辑模版,还是步骤繁琐、困难重重,制作的模板也容易出现一些问题,为此,PageOffice提供了定义模板的接口,由开发人员使用程序预先定义好用户可以使用的数据区域和数据标签,当用户编辑模版的时候,给用户弹出一个数据区域和数据标签的选择窗口,用户只需要选择使用这些数据区域和数据标签插入到word模版中,设置好数据的段落格式、字体、样式、颜色等等。这样以来,不但处理好了约定的问题,而且使得用户自定义模板的操作更加简单快捷。

    一、 使用PageOffice提供的编辑模版功能:

    PageOffice给开发人员提供了定义模版的接口DefineDataRegion和DefineDataTag方法,

    • PageOffice.WordWriter.WordDocument.Template.DefineDataRegion
    • PageOffice.WordWriter.WordDocument.Template.DefineDataTag

    1. 使用DefineDataRegion定义数据区域,例如Java代码如下:
            WordDocument doc = new WordDocument();
            doc.getTemplate().defineDataRegion("Name", "[ 姓名 ]");
            doc.getTemplate().defineDataRegion("Address", "[ 地址 ]");
            doc.getTemplate().defineDataRegion("Tel", "[ 电话 ]");
            doc.getTemplate().defineDataRegion("Phone", "[ 手机 ]");
            doc.getTemplate().defineDataRegion("Sex", "[ 性别 ]");
            doc.getTemplate().defineDataRegion("Age", "[ 年龄 ]");
            doc.getTemplate().defineDataRegion("Email", "[ 邮箱 ]");
            doc.getTemplate().defineDataRegion("QQNo", "[ QQ号 ]");
            doc.getTemplate().defineDataRegion("MSNNo", "[ MSN号 ]");
    

    或者用ASP.NET开发的话,代码如下:

    	    PageOffice.WordWriter.WordDocument doc = new PageOffice.WordWriter.WordDocument();
            doc.Template.DefineDataRegion("Name", "[ 姓名 ]");
            doc.Template.DefineDataRegion("Address", "[ 地址 ]");
            doc.Template.DefineDataRegion("Tel", "[ 电话 ]");
            doc.Template.DefineDataRegion("Phone", "[ 手机 ]");
            doc.Template.DefineDataRegion("Sex", "[ 性别 ]");
            doc.Template.DefineDataRegion("Age", "[ 年龄 ]");
            doc.Template.DefineDataRegion("Email", "[ 邮箱 ]");
            doc.Template.DefineDataRegion("QQNo", "[ QQ号 ]");
            doc.Template.DefineDataRegion("MSNNo", "[ MSN号 ]");
    

    开发人员用服务器端程序定义好用户可使用的数据区域,用户在客户端编辑模版的时候就可以使用这些数据区域。注意,这里的代码中不需要写PO_ 开头,PageOffice会自动添加这个前缀。用户编辑模版时看到的数据区域管理窗口,如下图所示:

    1712

    左侧“待添加数据区域”列表是可以用户目前可以使用的数据区域,右侧“已添加数据区域”列表是文档中已经添加的数据区域。此窗口的实现代码已经由PageOffice封装完毕,无需开发人员自己写复杂的js+html代码去实现,并且此窗口中内容的样式是可以修改的,如果对那些样式不太满意,只需要对此窗口html代码的样式做简单的调整即可。用户编辑数据区域时的效果,如下图所示:

    1713

    1. 使用DefineDataTag定义数据标签,例如Java的代码如下:
    		WordDocument doc = new WordDocument();
            doc.getTemplate().defineDataTag("{ 甲方 }");
    		doc.getTemplate().defineDataTag("{ 乙方 }");
    		doc.getTemplate().defineDataTag("{ 担保人 }");
    		doc.getTemplate().defineDataTag("【 合同日期 】");
    		doc.getTemplate().defineDataTag("【 合同编号 】");
    

    或者用ASP.NET开发的代码如下:

            PageOffice.WordWriter.WordDocument doc = new PageOffice.WordWriter.WordDocument();
            doc.Template.DefineDataTag("{ 甲方 }");
            doc.Template.DefineDataTag("{ 乙方 }");
            doc.Template.DefineDataTag("{ 担保人 }");
            doc.Template.DefineDataTag("【 合同日期 】");
            doc.Template.DefineDataTag("【 合同编号 】");
    

    开发人员用服务器端程序定义好用户可使用的数据标签,用户在客户端编辑模版的时候就可以使用这些数据标签。用户编辑模版时看到的数据标签管理窗口,如下图所示:

    1714

    同数据区域一样,对此窗口的实现代码,PageOffice也已经封装完毕,无需开发人员自己写复杂的js+html代码去实现,并且此窗口中内容的样式是可以修改的,如果对那些样式不太满意,只需要简单的调整一下此窗口html代码中的样式即可。开发人员只管编写程序给数据标签赋值对应的数据,用户自己定义模版的样式、数据位置和数据的多少,用户可以使用全部的数据区域,也可以只使用部分, PageOffice在生成文件的时候,会自动忽略没有使用的数据标签,而不需要开发人员做任何代码的调整。

    与数据区域的管理不同的是,由于数据标签在文件中不是唯一的,所以不管在文件中添加了多少个数据标签,在数据标签管理窗口中的数据标签都是不会减少的。

    二. 使用PageOffice.WordWriter 命名空间中的对象填充数据到Word模版,动态生成文档:

    • PageOffice.WordWriter.WordDocument.OpenDataRegion 方法
    • PageOffice.WordWriter.WordDocument.OpenDataTag 方法

    开发人员只需要使用上面的两个方法,针对word模版编写程序,给所有的数据区域和数据标签赋值相应的数据即可,无需关心模版中到底使用了多少个数据区域和数据标签,那些Word模版中从来没有使用过的数据区域和数据标签,PageOffice会自动忽略,而无需开发人员做任何代码的修改,从而完美实现用户自定义模板的需求。

    Java开发的赋值代码如下:

    	    WordDocument doc = new WordDocument();
            doc.openDataRegion("Name").setValue("张三");        
            doc.openDataRegion("Age").setValue("21");  
    		……
            doc.openDataTag("{ 甲方公司名称 }").setValue("微软中国总部"); 
            doc.openDataTag("{ 乙方公司名称 }").setValue( "北京幻想科技公司"); 
    		……
            poCtrl.setWriter(doc);
    

    ASP.NET开发的赋值代码如下,

            PageOffice.WordWriter.WordDocument doc = new PageOffice.WordWriter.WordDocument();
            doc.OpenDataRegion("Name").Value = "张三";        
            doc.OpenDataRegion("Age").Value = "21";
    		……
            doc.OpenDataTag("{ 甲方公司名称 }").Value = "微软中国总部";
            doc.OpenDataTag("{ 乙方公司名称 }").Value = "北京幻想科技公司";
    		……
            PageOfficeCtrl1.SetWriter(doc);
    

    详细请参考PageOffice开发包里Samples4中的相关示例演示:
    二、30、用户自定义模板中数据区域(DataRegion)的位置(专业版、企业版)
    二、31、用户自定义模板中数据标签(DataTag)的位置(专业版、企业版)
    三、12、实现“用户自定义Word模板”动态生成文件(专业版、企业版)

    展开全文
  • manage_template => true # 自定义索引 按照天拆分 index => "my-log-%{+YYYY.MM.dd}" # 自定义类型 document_type=> "_doc" # 映射模板文件所在位置 template => "/usr/share/logstash/templates/my-log.json" #...

    1 首先配置logstash.conf

    # 输入来自filebeat
    input {
      beats {
        port => "5044"
      }
    }
    
    # 过滤器
    filter {
    
            grok {
                    match =>{
                            "message"=>"(?<data>({.*}))"
                    }
            }
    
            grok {
                    match =>{
                            "message"=>"%{TIMESTAMP_ISO8601:logTime}"
                    }
            }
    
            grok {
                    match =>{
                            "message"=>"%{LOGLEVEL:logLevel}"
                    }
            }
    
    
            grok {
                    match => {
                            "message"=>"(?<userId>(?<=\"userId\":)(\d+))"
                    }
            }
    
            # 设置东八区时间
            ruby {
                    code => "event.set('logstashTime', event.get('@timestamp').time.localtime + 8*60*60);
                            event.set('@timestamp', event.get('logstashTime'))"
            }
    		
    		# 忽略字段
            mutate {
                    remove_field => "offset"
                    remove_field => "@version"
                    remove_field => "input_type"
                    # remove_field => "beat"
                    remove_field => "host"
                    remove_field => "source"
                    remove_field => "type"
                    remove_field => "tags"
                    remove_field => "prospector"
                    remove_field => "input"
                    remove_field => "log"
            }
    
    }
    
    # 输出追加到日志中
    output {
      stdout { codec => rubydebug }
    }
    
    # 输出到es
    output {
      elasticsearch {
      	# host
        hosts => ["http://elasticsearch:9200"]
        # 开启logstash自动管理模板功能,默认manage_template参数为true, 否则logstash将不会调用Elasticsearch API创建模板。  
        manage_template => true
        # 自定义索引 按照天拆分
        index => "my-log-%{+YYYY.MM.dd}"
        # 自定义类型
        document_type=> "_doc"
        # 映射模板文件所在位置
        template => "/usr/share/logstash/templates/my-log.json"
        #template_name => "my-log"
        # 是否覆盖已存在的模板,template_overwrite为true则template的order高的,满足同样条件(如均以searchlog-开头)的template将覆盖order低的
        template_overwrite => true
      }
    }
    
    

    2 配置模板文件 my-log.json

    {
    		# 按照名字匹配
            "template": "my-log-*",
            # 排序
            "order": 1,
            # 索引分片等配置
            "settings": {
                    "number_of_shards": 1,
                    "number_of_replicas": 0,
                    "refresh_interval": "60s"
            },
            # 映射
            "mappings": {
                    "_doc": {
                    		# 严格映射
                            "dynamic":"strict",
                            "properties": {
    
                                    "message": {
                                    		# 分词器
                                            "analyzer": "ik_max_word",
                                            "index": true,
                                            "store": false,
                                            "type": "text"
                                    },
    
                                    "data": {
                                            "analyzer": "ik_max_word",
                                            "index": true,
                                            "store": false,
                                            "type": "text"
                                    },
    
                                    "userId": {
                                            "type": "long"
                                    },
    
                                    "logLevel": {
                                            "store": false,
                                            "type": "keyword"
                                    },
                                    "from": {
                                            "store": false,
                                            "type": "keyword"
                                    },
    
                                    ""      
                                    "@timestamp": {
                                            "format": "strict_date_optional_time||yyyy-MM-dd HH:mm:ss.SSS||epoch_millis",
                                            "type": "date"
                                    },
    
                                    "logstashTime": {
                                            "format": "strict_date_optional_time||yyyy-MM-dd HH:mm:ss.SSS||epoch_millis",
                                            "type": "date"
                                    },
    
                                    "logTime": {
                                            "format": "strict_date_optional_time||yyyy-MM-dd HH:mm:ss.SSS||epoch_millis",
                                            "type": "date"
                                    },
    
                                            "type": "date"
                                    },
    
                                    "beat": {
                                            "properties": {
                                                    "hostname": {
                                                            "store": false,
                                                            "type": "keyword"
                                                    },
                                                    "name": {
                                                            "store": false,
                                                            "type": "keyword"
                                                    },
                                                    "version": {
                                                            "store": false,
                                                            "type": "keyword"
                                                    }
                                            }
                                    }
    
                            }
                    }
            }
    }
    
    

    3 关于日期的format

    "format": "strict_date_optional_time||yyyy-MM-dd HH:mm:ss.SSS||epoch_millis",
    分别对应日期格式 =>
    2021-09-09T17:19:21.262Z||2021-09-09 17:19:20.000||时间戳
    
    

    4 关于"dynamic"字段

    一般的,mapping则又可以分为动态映射(dynamic mapping)和静态(显式)映射(explicit mapping)和精确(严格)映射(strict mappings),具体由dynamic属性控制。

    • 动态映射(dynamic:true)
    • 静态映射(dynamic:false)
    • 严格模式(dynamic:strict)

    前言

    一般的,mapping则又可以分为动态映射(dynamic mapping)和静态(显式)映射(explicit mapping)和精确(严格)映射(strict mappings),具体由dynamic属性控制。

    动态映射(dynamic:true)

    现在有这样的一个索引:

    PUT m1
    {
      "mappings": {
        "doc":{
          "properties": {
            "name": {
              "type": "text"
            },
            "age": {
              "type": "long"
            }
          }
        }
      }
    }
    

    通过GET m1/_mapping看一下mappings信息:

    {
      "m1" : {
        "mappings" : {
          "doc" : {
            "dynamic" : "true",
            "properties" : {
              "age" : {
                "type" : "long"
              },
              "name" : {
                "type" : "text"
              }
            }
          }
        }
      }
    }
    

    添加一些数据,并且新增一个sex字段:

    PUT m1/doc/1
    {
      "name": "小黑",
      "age": 18,
      "sex": "不详"
    }
    

    当然,新的字段查询也没问题:

    GET m1/doc/_search
    {
      "query": {
        "match": {
          "sex": "不详"
        }
      }
    }
    

    返回结果:

    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 1,
        "max_score" : 0.5753642,
        "hits" : [
          {
            "_index" : "m1",
            "_type" : "doc",
            "_id" : "1",
            "_score" : 0.5753642,
            "_source" : {
              "name" : "小黑",
              "age" : 18,
              "sex" : "不详"
            }
          }
        ]
      }
    }
    

    现在,一切都很正常,跟elasticsearch自动创建时一样。那是因为,当 Elasticsearch 遇到文档中以前未遇到的字段,它用动态映射来确定字段的数据类型并自动把新的字段添加到类型映射。我们再来看mappings你就明白了:

    {
      "m1" : {
        "mappings" : {
          "doc" : {
            "dynamic" : "true",
            "properties" : {
              "age" : {
                "type" : "long"
              },
              "name" : {
                "type" : "text"
              },
              "sex" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              }
            }
          }
        }
      }
    }
    

    通过上例可以发下,elasticsearch帮我们新增了一个sex的映射。所以。这一切看起来如此自然。这一切的功劳都要归功于dynamic属性。我们知道在关系型数据库中,字段创建后除非手动修改,则永远不会更改。但是,elasticsearch默认是允许添加新的字段的,也就是dynamic:true
    其实创建索引的时候,是这样的:

    PUT m1
    {
      "mappings": {
        "doc":{
          "dynamic":true,
          "properties": {
            "name": {
              "type": "text"
            },
            "age": {
              "type": "long"
            }
          }
        }
      }
    }
    

    上例中,当dynamic设置为true的时候,elasticsearch就会帮我们动态的添加映射属性。也就是等于啥都没做!
    这里有一点需要注意的是:mappings一旦创建,则无法修改。因为Lucene生成倒排索引后就不能改了。

    静态映射(dynamic:false)

    现在,我们将dynamic值设置为false

    PUT m2
    {
      "mappings": {
        "doc":{
          "dynamic":false,
          "properties": {
            "name": {
              "type": "text"
            },
            "age": {
              "type": "long"
            }
          }
        }
      }
    }
    

    现在再来测试一下falsetrue有什么区别:

    PUT m2/doc/1
    {
      "name": "小黑",
      "age":18
    }
    PUT m2/doc/2
    {
      "name": "小白",
      "age": 16,
      "sex": "不详"
    }
    

    第二条数据相对于第一条数据来说,多了一个sex属性,我们以sex为条件来查询一下:

    GET m2/doc/_search
    {
      "query": {
        "match": {
          "sex": "不详"
        }
      }
    }
    

    结果如下:

    {
      "took" : 0,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 0,
        "max_score" : null,
        "hits" : [ ]
      }
    }
    

    结果是空的,也就是什么都没查询到,那是为什呢?来GET m2/_mapping一下此时m2mappings信息:

    {
      "m2" : {
        "mappings" : {
          "doc" : {
            "dynamic" : "false",
            "properties" : {
              "age" : {
                "type" : "long"
              },
              "name" : {
                "type" : "text"
              }
            }
          }
        }
      }
    }
    

    可以看到elasticsearch并没有为新增的sex建立映射关系。所以查询不到。
    当elasticsearch察觉到有新增字段时,因为dynamic:false的关系,会忽略该字段,但是仍会存储该字段。
    在有些情况下,dynamic:false依然不够,所以还需要更严谨的策略来进一步做限制。

    严格模式(dynamic:strict)

    让我们再创建一个mappings,并且将dynamic的状态改为strict

    PUT m3
    {
      "mappings": {
        "doc": {
          "dynamic": "strict", 
          "properties": {
            "name": {
              "type": "text"
            },
            "age": {
              "type": "long"
            }
          }
        }
      }
    }
    

    现在,添加两篇文档:

    PUT m3/doc/1
    {
      "name": "小黑",
      "age": 18
    }
    PUT m3/doc/2
    {
      "name": "小白",
      "age": 18,
      "sex": "不详"
    }
    

    第一篇文档添加和查询都没问题。但是,当添加第二篇文档的时候,你会发现报错了:

    {
      "error": {
        "root_cause": [
          {
            "type": "strict_dynamic_mapping_exception",
            "reason": "mapping set to strict, dynamic introduction of [sex] within [doc] is not allowed"
          }
        ],
        "type": "strict_dynamic_mapping_exception",
        "reason": "mapping set to strict, dynamic introduction of [sex] within [doc] is not allowed"
      },
      "status": 400
    }
    

    错误提示,严格动态映射异常!说人话就是,当dynamic:strict的时候,elasticsearch如果遇到新字段,会抛出异常。
    上述这种严谨的作风洒家称为——严格模式!

    小结:

    • 动态映射(dynamic:true):动态添加新的字段(或缺省)。
    • 静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现在查询中。
    • 严格模式(dynamic: strict):如果遇到新的字段,就抛出异常。

    一般静态映射用的较多。就像HTMLimg标签一样,src为自带的属性,你可以在需要的时候添加id或者class属性。
    当然,如果你非常非常了解你的数据,并且未来很长一段时间不会改变,strict不失为一个好选择。


    展开全文
  • 创建TPL自定义模板

    千次阅读 2017-03-30 14:41:35
    创建初始模板所需要的文件和文件夹    1.index.php主文件,用于编写业务逻辑  2.template.inc.php模板初始化文件,用于初始化模板信息  3.templates目录用于存放所有的模板文件  1)index.tpl模板文件  4....
  • OCR识别身份证、营业执照、增值税发票、自定义模板 应用场景: 最近在做一个票据平台,需要使用者上传营业执照和法人身份证进行识别,同时还有一些增值税发票识别、票据识别等图像识别功能,因此整理一下OCR图像识别...
  • 微软word开机自启动A great cover page draws in readers. If you use Microsoft Word, you’re in luck, because Word has ready to use cover pages. But did you know that Word also lets you create custom ...
  • 无需关心模版中到底使用了多少个数据区域和数据标签,那些Word模版中从来没有使用过的数据区域和数据标签,PageOffice会自动忽略,而无需开发人员做任何代码的修改,从而完美实现用户自定义模板的需求。 Java开发...
  • poi-tl(poi-template-language) Word 模板引擎,基于Apache POI - the Java API for Microsoft Documents。What is poi-tlFreeMarker、Velocity基于文本模板和数据生成新的HTML页面、配置文件等,poi-tl是Word模板...
  • 列表|表尾]导出到Excel文件,因为格式繁多一个个固定代码编写很不现实,网上找了很久都没有相关的功能实例,于是就加班自己动手写了一个通用的导出实例,应用到代码中。现为方便广大开发者遍历特上传通用精简版分享给...
  • WORD模板使用技巧一点通.docxWORD模板使用技巧一点通●文/图翁永平大家知道,Word提供了各式各样的模 板,当在制作专业的文档之前,看看没有现成的模板可用,如果答案是肯定的, 那么就发挥“拿来主义”的精神吧,...
  • hello大家好,今天我要给大家推荐一个非常棒的Word专用的模板引擎,Poi-tl(Poi-...常见的模板基本上都是文本格式的,比如 html 格式的、text 格式的,这种格式模板处理起来相对比较容易,对应的模板引擎很多,比如
  • 封条格式word怎么打

    千次阅读 2021-01-15 02:22:31
    再把文本框格式设置成白色,文本框也就没黑边了。2回答2020-12-07浏览:1分类:办公入门回答:你重新回到第一段的“一、”处,删除“一、”再重新输入同样的“一、”然后按一下键盘上的Ctrl+z键退回一步操作它自己就...
  • 就想着是不是可以一种方法可以批量修改表格样式,然后搜了搜并实践了一下,确实很便捷,记录并分享下。 (不过,我文档中并没有用到,这些能一次性修改所有表格的通用属性字号、颜色、间距啥的,但我是需要修改列...
  • 不同期刊有不同的参考文献引用格式,有时已有的参考文献引用格式并不适用当前的期刊,所以需要自适应的去设计与修改这个引用格式自定义参考文献的引用格式的过程还是稍微有些复杂的,我大概花了一个晚上加一个...
  • 使用POI 导出word模板文件

    千次阅读 热门讨论 2019-03-21 11:29:32
    maven依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</version> </dependency>...自定义XWPFDocu...
  • Dynamics 365 中三个位置您可以创建 Word 模板: 从“设置”页。 转到设置 > 模板 > 文档模板 > 新建()。 您需要具有足够的权限来访问“设置”页面,例如系统管理员或系统定制员。 从记录中。 打开...
  • poi使用模板导出word带图片

    千次阅读 2016-11-15 16:17:05
    1.下面是我做的加载模板导出带图片的word的导出方式,使用之前请映入freemarker的jar包,可以从百度下载即可。 2.首先准备到你要导出的word模板,在要填充的模板中填入el表达式,如下图所示。 XXXX公司招聘高校毕业...
  • 目前SuperSet CSS版本0.38.0(跟版本无关,只是声明一下); 因为对前端不熟悉,且网上资源实在匮乏; 求好看的自定义SuperSet CSS模板或者有关SuperSet CSS的参考网址~
  • C. “格式”菜单中的“制表位”命令D. “格式”菜单中的“字体”命令 )...字号是4、在 Word 中进行“页面设定”,主要是修改页面的( 时间:120 分钟 总分:100 分 A. 字符数/行数、页边距、分栏数、版面 C. 页边距...
  • 这不,今天给大家带来了《自定义maven插件:自动生成API的word文档》。 老规矩,先上镇楼图。(读者们也可以研究下Swagger2生成doc文档) 开门见山,直接上开发教程!首先是插件配置: &lt;plugin&gt;...
  • word模板运用

    千次阅读 2012-12-26 20:57:22
    大家知道,Word提供了各式各样的模板,在开始编辑Word文档尤其是专业性质的文档之前,先看看没有现成的模板可用吧。如果,那么大可以发挥“拿来主义”的精神,利用现成的模板来制作,这样一来,不但作品的质量会...
  • 我既是作者也是编辑,每个月同事都会发给我几篇具有特殊格式样式的 Microsoft Word 文档,而且似乎每篇文档都不同的格式样式。“样式”是一种格式类型,用于 Word 文档中的特定内容部分。例如,同事一周内发给我 ...
  • Java Poi流 根据模板生成Word报告

    千次阅读 2020-03-12 09:23:55
    试验了好几天,终于实现Java Poi流根据Word模板插入相应的文本、表格和图片,并生成新的Word报告。
  • 这里主要记录使用 Word 2013 版本的 Microsoft office Word 软件进行论文书写时的一些常用的格式设置技巧,以供分享与记录。  Word文档页脚添加页码  Word设置多级标题格式 Word文档页脚添加页码  编辑页眉...
  • 若要隐藏输入的图片,请选取“图片框”复选框,Microsoft Word 将只显示该图片的轮廓。清除“图形”复选框隐藏用自选图形 (自选图形:一组现成的形状,包括如矩形和圆这样的基本形状,以及各种线条和连接符、箭头...
  • 本编文章继SpringBoot+Poi-tl根据Word模板动态生成word(含动态行表格)文章之后 介绍Poi-tl导出word的延伸功能: 所需依赖以及word模板所属位置 见 SpringBoot+Poi-tl根据Word模板动态生成word(含动态行表格),这里...
  • VC操作Word书签模板

    千次阅读 2016-08-19 16:14:08
    一 制作模板   1 新建一个文档,设置文档内容。对于循环的部分,建议放到表格内,这样容易定位、选择、复制、粘贴。 2 将鼠标定位到要插入书签的位置,从菜单上,“插入”->“书签,弹出对话框,输入书签名,点击...
  • 文章目录自定义指令:全局:局部指令:自定义过滤器:全局:局部: 自定义指令: vue中提供了丰富的内置指令,如v-if,v-bind,v-on…,除此之外我们还可以通过全局的自定义指令Vue.directive({})或者局部的自定义指令...
  • word批量修改表格属性

    千次阅读 2021-09-05 10:57:12
    (1)打开要修改word——文件——选项——自定义功能区——将开发工具选上——确定。 (2)开发工具——宏——拷贝以下代码:(以下代码功能是选中所有表格) Sub 批量修改表格() Dim tempTable As Table ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,535
精华内容 5,814
关键字:

word自定义模板可修改已有格式