\n * 提供列表和函数作为数据源\n */\npublic static void writeAutoWriter() {\n final String fileName = defaultFileName(\"writeAutoWriter\");\n EasyExcelFactory.write(fileName)\n .head(Item.class)\n .sheet(\"模板\")\n .doWrite(WriteSample::sampleItems);\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"EasyExcel提供了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"EasyExcelFactory","attrs":{}}],"attrs":{}},{"type":"text","text":"类,API方法也是fluent方式,可以如丝般顺滑的实现生成Excel文件。如果感觉","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"EasyExcelFactory","attrs":{}}],"attrs":{}},{"type":"text","text":"太长,还可以直接写作","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"EasyExcel","attrs":{}}],"attrs":{}},{"type":"text","text":",这是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"EasyExcelFactory","attrs":{}}],"attrs":{}},{"type":"text","text":"的子类,类似于别名。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不过,这种别名定义方式,在有些规范中属于","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"smell code","attrs":{}}],"attrs":{}},{"type":"text","text":",所以,根据自己或者公司规范选择吧。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.EasyExcelFactory#write(java.lang.String)","attrs":{}}],"attrs":{}},{"type":"text","text":"方法的参数传的是导出文件的文件名,如果并不需要生成文件,只需要创建文件流,也可以传入一个输出流","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"OutputStream","attrs":{}}],"attrs":{}},{"type":"text","text":",这样就可以更加灵活的实现生成逻辑了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.metadata.AbstractParameterBuilder#head()","attrs":{}}],"attrs":{}},{"type":"text","text":"方法是定义表头,只要传入一个类,就会读取这个类的所有字段作为表头。如果字段上","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.annotation.ExcelProperty","attrs":{}}],"attrs":{}},{"type":"text","text":"注解,定义了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"value","attrs":{}}],"attrs":{}},{"type":"text","text":",就会取","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"value","attrs":{}}],"attrs":{}},{"type":"text","text":"的值作为表头。此处还有很多操作,比如,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"value","attrs":{}}],"attrs":{}},{"type":"text","text":"是数组,可以定义多个,如果是相邻字段定义了相同的表头,会合并单元格,表体内容会选择第一个单元格的内容。这个注解还可以定义","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"index","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"order","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"converter","attrs":{}}],"attrs":{}},{"type":"text","text":"等,后面会一一给出例子。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.write.builder.ExcelWriterBuilder#sheet()","attrs":{}}],"attrs":{}},{"type":"text","text":"方法定义工作表,有多个重载方法,可以定义","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sheetNo","attrs":{}}],"attrs":{}},{"type":"text","text":"指明是第几个工作表,可以传入","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sheetName","attrs":{}}],"attrs":{}},{"type":"text","text":"指明工作表名称。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.write.builder.ExcelWriterSheetBuilder#doWrite()","attrs":{}}],"attrs":{}},{"type":"text","text":"方法就是写Excel文件了,传入全部的列表数据,或者使用Java8+的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Supplier","attrs":{}}],"attrs":{}},{"type":"text","text":"函数。还可以实现分页写入,后面会给出例子。这个方法会自动关闭文件流,真是很贴心。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"结果为:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a0/a0de5cb490bf6616084bed5a19ec208c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"根据头对象和列表向多个工作表中写数据","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面是向一个工作表写数据,接下来我们向多个工作表写数据。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个例子会涉及更多的内部对象,比如:ExcelWriter、WriteSheet。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"/**\n * 手动创建{@link com.alibaba.excel.ExcelWriter},指定sheet写入数据。\n *
\n * 提供列表和函数作为数据源\n */\npublic static void writeManualWither() {\n String fileName = defaultFileName(\"writeManualWriter\");\n ExcelWriter excelWriter = null;\n try {\n excelWriter = EasyExcelFactory.write(fileName)\n .head(Item.class)\n .build();\n final WriteSheet writeSheet1 = EasyExcelFactory.writerSheet(\"模板1\").build();\n excelWriter.write(WriteSample::sampleItems, writeSheet1);\n\n final WriteSheet writeSheet2 = EasyExcelFactory.writerSheet(\"模板2\").build();\n excelWriter.write(sampleItems(), writeSheet2);\n } finally {\n // 千万别忘记finish 会帮忙关闭流\n if (excelWriter != null) {\n excelWriter.finish();\n }\n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因为是想多个工作表中写数据,我们就不能直接使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"doWrite","attrs":{}}],"attrs":{}},{"type":"text","text":"方法了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.ExcelWriter","attrs":{}}],"attrs":{}},{"type":"text","text":"类是Excel写对象,用来创建Excel工作簿的。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.write.metadata.WriteSheet","attrs":{}}],"attrs":{}},{"type":"text","text":"类是Sheet写对象,用来创建Sheet工作表的。通过","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.ExcelWriter#write()","attrs":{}}],"attrs":{}},{"type":"text","text":"方法,指定写入数据和写入的目标工作表,就可以实现向多个工作表中写数据的功能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此处需要注意,我们在创建","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ExcelWriter","attrs":{}}],"attrs":{}},{"type":"text","text":"对象时,调用了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"head()","attrs":{}}],"attrs":{}},{"type":"text","text":"方法定义了表头,这是整个Excel的定义,sheet会继承这个定义。这样,整个Excel文件中的所有工作表,表头都是相同的。不要停,后面会给出不同工作表定义不同表头的示例。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"结果为:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8f/8f2c86fea7f678a4456af7727f7feeb6.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"按照定义指定导出列","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在后台系统中,会有行列权限的控制。行权限,通过数据行实现,只导出有权限的行数据即可。列权限,可以通过只导出有权限的列,排除没有权限的列(通常是分等级的敏感数据)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有时候需要定制化导出,导出所有列表格比较大,用户根据需要指定需要导出的列。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"排除指定列","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"private static void writeExcludeColumn() {\n String fileName = defaultFileName(\"writeExcludeColumn\");\n Set \n * 可以实现多层表头。\n */\nprivate static void writeDynamicHead() {\n String fileName = defaultFileName(\"writeDynamicHead\");\n EasyExcelFactory.write(fileName)\n .head(dynamicHead())\n .sheet()\n .doWrite(sampleItems());\n}\n\nprivate static List>}格式数据。\n *
> dynamicHead() {\n List
> heads = new ArrayList<>();\n final List
>","attrs":{}}],"attrs":{}},{"type":"text","text":"类型的数据即可。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"结果为:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5e/5ed1e13df09a2fc9feac3f6ec17c0197.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当然,这样做还不是彻底的动态。我们可以使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"com.alibaba.excel.write.builder.ExcelWriterSheetBuilder#doWrite(java.util.Collection>)","attrs":{}}],"attrs":{}},{"type":"text","text":"实现动态表体。代码如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"private static void writeDynamicData() {\n String fileName = defaultFileName(\"writeDynamicData\");\n EasyExcelFactory.write(fileName)\n .head(dynamicHead())\n .sheet()\n .doWrite(dynamicData());\n}\n\nprivate static List
> dynamicData() {\n List
> list = new ArrayList<>();\n for (int i = 0; i < 10; i++) {\n List