当前位置:   article > 正文

java手动/按模板生成word与excel_java根据模板生成excel文件

java根据模板生成excel文件

目录

一、前言

二、生成word

1、使用Apache poi手动生成一个word

(1)导入依赖

(2)手动生成一个包含表格的word

2、使用Apache poi 按模板生成一个简单的word

(1)导入依赖如上,注意只有高一点版本的poi-tl才有模板策略,即LoopRowTableRenderPolicy

(2)模板样式

 (3)代码示例

(4)模板说明

3、使用easypoi按模板生成一个word(包含easypoi生成word的合并)

(1)导入依赖

(2)模板样式

(3)模板说明

(4)代码示例

三、生成excel

1、使用Apache poi 手动生成一个简单的excel

(1)导入依赖

(2)代码示例

2、使用easyexcel按模板生成excel

(1)导入依赖

(2)模板样式

(3)代码示例

 3、使用jxls 1.0.6 按模板生成excel

(1)导入依赖

(2)模板样式及说明 

(3)代码示例

4、使用jxls 2.10.0 按模板生成excel(有条件还是使用新版好,生成excel合并格式也都完整,老版的合并单元格还是有问题需要自己调整)

(1)导入依赖

(2)模板样式

(3)模板说明

(4)代码示例


一、前言

     最近项目遇到生成word,excel的问题,但由于jar包冲突,版本不符合要求等原因,小白使用了许多方法来完成目的,基本都是不断度娘,今天来汇总一下,代码注释中加了些个人的粗浅理解,望误喷。

      先说一下,本文中,生成word描述了使用Apache poi,easypoi工具的方法,生成excel描述了使用Apache poi,easyexcel,jxls工具的方法,可选择观看

二、生成word

1、使用Apache poi手动生成一个word

(1)导入依赖

  1. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi</artifactId>
  4. <version>4.1.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.poi</groupId>
  8. <artifactId>poi-ooxml</artifactId>
  9. <version>4.1.2</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.deepoove</groupId>
  13. <artifactId>poi-tl</artifactId>
  14. <version>1.10.0</version>
  15. </dependency>

(2)手动生成一个包含表格的word

  1. package cn.itcast.mp;
  2. import cn.itcast.mp.pojo.User;
  3. import org.apache.poi.xwpf.usermodel.*;
  4. import java.io.File;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. public class WordUtil {
  10. public static void main(String[] args) throws IOException {//普通生成word文件及其中的word表格
  11. List<User> users = new ArrayList<>();//造点数据,此处创建了User对象,属性id,userName,password,name,age,mail
  12. users.add(new User(1L, "zhangsan", "99999", "张三", 25, "test1@itcast.cn"));
  13. users.add(new User(2L, "zhangsan1", "88888", "张三1", 20, "test1@itcast.cn1"));
  14. users.add(new User(3L, "zhangsan2", "77777", "张三2", 23, "test1@itcast.cn2"));
  15. users.add(new User(4L, "zhangsan3", "66666", "张三3", 24, "test1@itcast.cn3"));
  16. users.add(new User(5L, "zhangsan4", "55555", "张三4", 28, "test1@itcast.cn4"));
  17. users.add(new User(6L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  18. XWPFDocument doc = new XWPFDocument();//Apache poi的一个文档对象,暂理解为创建了一个虚拟的word文档
  19. XWPFParagraph p = doc.createParagraph();//在这个word里新建一个段落
  20. p.setAlignment(ParagraphAlignment.CENTER);//设置段落的对齐方式
  21. p.setBorderBottom(Borders.DOUBLE);//设置下边框
  22. p.setBorderTop(Borders.DOUBLE);//设置上边框
  23. p.setBorderRight(Borders.DOUBLE);//设置右边框
  24. p.setBorderLeft(Borders.DOUBLE);//设置左边框
  25. XWPFRun r = p.createRun();//创建段落文本,即段落里要放入的内容
  26. r.setText("创建段落文本里的内容,set相当于放值");//内容赋值
  27. r.setBold(true);//内容设置为粗体
  28. r.setColor("FF0000");//内容设置颜色;此处不带#
  29. p = doc.createParagraph();//再创建一个段落
  30. r= p.createRun();//第二个段落中的文本
  31. r.setText("这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!");
  32. // XWPFParagraph p1 = doc.createParagraph();//这三句与上三句效果相同
  33. // XWPFRun r1 = p1.createRun();
  34. // r1.setText("这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!这里是段落内容!");
  35. XWPFTable table = doc.createTable(users.size() + 1, 6);//创建一个表格,括号中(几行,几列)
  36. table.getRow(0).getCell(0).setText("id");//设置表头
  37. table.getRow(0).getCell(1).setText("userName");//getRow获取第几行,getCell获取第几列,setText单元格赋值
  38. table.getRow(0).getCell(2).setText("password");
  39. table.getRow(0).getCell(3).setText("name");
  40. table.getRow(0).getCell(4).setText("age");
  41. table.getRow(0).getCell(5).setText("mail");
  42. for (int i = 0; i < users.size(); i++) {//使用双层循环,并用以上单元格赋值方法,给单元格一个一个赋值
  43. for (int j = 0; j < 6; j++) {
  44. if (j == 0) {
  45. table.getRow(i+1).getCell(j).setText(users.get(i).getId().toString());
  46. } else if (j == 1) {
  47. table.getRow(i + 1).getCell(j).setText(users.get(i).getUserName());
  48. } else if (j == 2) {
  49. table.getRow(i + 1).getCell(j).setText(users.get(i).getPassword());
  50. } else if (j == 3) {
  51. table.getRow(i + 1).getCell(j).setText(users.get(i).getName());
  52. } else if (j == 4) {
  53. table.getRow(i+1).getCell(j).setText(users.get(i).getAge().toString());
  54. } else if (j == 5) {
  55. table.getRow(i + 1).getCell(j).setText(users.get(i).getMail());
  56. }
  57. }
  58. }
  59. table.setTableAlignment(TableRowAlign.CENTER);//表格居中
  60. String savePath = "D:\\poi";//生成word后要保存到的位置
  61. String fileName = "PoiWord";//生成的word的名字
  62. createDoc(doc, savePath, fileName);//调用下面poi生成word的方法
  63. }
  64. public static void createDoc(XWPFDocument document, String savePath, String fileName) throws IOException {
  65. File file = new File(savePath);//按照路径先生成一个文件,用于判断是否存在目录
  66. if (!file.exists()) {
  67. // 判断生成目录是否存在,不存在时创建目录。
  68. file.mkdirs();
  69. }
  70. // 保存
  71. fileName += ".docx";//后缀
  72. FileOutputStream out = new FileOutputStream(new File(savePath + File.separator + fileName));//生成word文件以输出流的方式,输出用于文件的写入
  73. document.write(out);//poi的write方法,把虚拟word中的数据写入刚创建的word文件里
  74. // 关闭资源
  75. out.flush();
  76. out.close();
  77. document.close();
  78. }
  79. }

2、使用Apache poi 按模板生成一个简单的word

(1)导入依赖如上,注意只有高一点版本的poi-tl才有模板策略,即LoopRowTableRenderPolicy

(2)模板样式

 (3)代码示例

  1. import cn.itcast.mp.pojo.User;
  2. import com.deepoove.poi.XWPFTemplate;
  3. import com.deepoove.poi.config.Configure;
  4. import com.deepoove.poi.data.TextRenderData;
  5. import com.deepoove.poi.data.Texts;
  6. import com.deepoove.poi.data.style.Style;
  7. import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
  8. import java.io.File;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. public class WordTest {//模板生成word表格
  14. public static void main(String[] args) {
  15. try {
  16. List<User> users = new ArrayList<>();//造点数据
  17. users.add(new User(1L, "zhangsan", "99999", "张三", 25, "test1@itcast.cn"));
  18. users.add(new User(2L, "zhangsan1", "88888", "张三1", 20, "test1@itcast.cn1"));
  19. users.add(new User(3L, "zhangsan2", "77777", "张三2", 23, "test1@itcast.cn2"));
  20. users.add(new User(4L, "zhangsan3", "66666", "张三3", 24, "test1@itcast.cn3"));
  21. users.add(new User(5L, "zhangsan4", "55555", "张三4", 28, "test1@itcast.cn4"));
  22. users.add(new User(6L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  23. List<Map<String,Object>> empList = new ArrayList<>();//必须是List<Map>型几个的数据才可以显示出来
  24. for (int i = 0; i < users.size(); i++) {
  25. Map<String, Object> map = new HashMap<>();
  26. map.put("id",users.get(i).getId());
  27. map.put("userName",users.get(i).getUserName());
  28. map.put("password",users.get(i).getPassword());
  29. map.put("name",users.get(i).getName());
  30. map.put("age",users.get(i).getAge());
  31. map.put("mail",users.get(i).getMail());
  32. empList.add(map);
  33. }
  34. Map<String,Object> empList1 = new HashMap<>();
  35. empList1.put("empList",empList);
  36. empList1.put("empList1",empList);
  37. empList1.put("title",new TextRenderData("F04B09","POI创建的Word段落文本"));
  38. String content = "这是测试!这是测试!这是测试!这是测试!这是测试!这是测试!这是测试!这是测试!这是测试!";
  39. Style style = Style.builder().buildColor("18282B").buildUnderlineColor("F04B09").build();//设置样式
  40. empList1.put("content", Texts.of(content).style(style).create());//加入样式
  41. // 模板文件地址
  42. String filePath = "D:\\poi\\WordTem.docx";
  43. // 读取模板后保存生成word的地址
  44. String outPath = "D:\\poi\\wordTest.docx";
  45. // 为表格的显示绑定循环政策
  46. LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
  47. // 将empList设置为行循环绑定的数据源的key,即key是empList的value会在模板中的{{empList}}处进行解析,可查看模板
  48. Configure configure = Configure.builder().bind("empList", policy).bind("empList1",policy).build();
  49. // 读取模板、数据并渲染,render中放入整体的模板map
  50. XWPFTemplate template = XWPFTemplate.compile(new File(filePath), configure).render(empList1);
  51. // 文件是否已存在,则删除
  52. File file = new File(outPath);
  53. if (file.exists()){
  54. file.delete();
  55. }
  56. // 生成word保存在指定目录(把生成好的模板word数据写入刚生成的文件中)
  57. template.writeToFile(outPath);
  58. template.close();
  59. } catch (Exception e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. }

(4)模板说明

  • {{xxx}}表示普通占位符

  • Configure configure = Configure.builder().bind("empList", policy).bind("empList1",policy).build();
  • 模板表格中id项{{xxx}}相当于一个标识,起名字就为以上代码bind中“ ”中的内容,想要几个表就bind几次

  • 表格中的各个字段用 [ ]

3、使用easypoi按模板生成一个word(包含easypoi生成word的合并)

(1)导入依赖

  1. <dependency>
  2. <groupId>cn.afterturn</groupId>
  3. <artifactId>easypoi-base</artifactId>
  4. <version>4.3.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>cn.afterturn</groupId>
  8. <artifactId>easypoi-web</artifactId>
  9. <version>4.3.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>cn.afterturn</groupId>
  13. <artifactId>easypoi-annotation</artifactId>
  14. <version>4.3.0</version>
  15. </dependency>
  16. <!--注意:word中要使用循环等标签必须单独导入以下依赖-->
  17. <dependency>
  18. <groupId>org.apache.poi</groupId>
  19. <artifactId>ooxml-schemas</artifactId>
  20. <version>1.4</version>
  21. </dependency>

(2)模板样式

 

(3)模板说明

  • {{xxx}}普通占位符

  • {{$fe:遍历集合的键名}} t就用t就行 此处注意循环标签括起了一整行

  • 还有,如果出现表格与数据堆在一起的情况,不行就多空几行,如图

(4)代码示例

  1. import cn.afterturn.easypoi.word.WordExportUtil;
  2. import cn.itcast.mp.pojo.User;
  3. import org.apache.poi.xwpf.usermodel.Document;
  4. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  5. import java.io.File;
  6. import java.io.FileOutputStream;
  7. import java.util.ArrayList;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. import java.util.Map;
  11. import org.apache.poi.xwpf.usermodel.XWPFPictureData;
  12. import org.apache.xmlbeans.XmlOptions;
  13. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
  14. import org.springframework.util.CollectionUtils;
  15. public class CreateWordEasy {
  16. public static void main(String[] args) {
  17. List<User> users = new ArrayList<>();//造点数据
  18. users.add(new User(1L, "zhangsan", "99999", "张三", 25, "test1@itcast.cn"));
  19. users.add(new User(2L, "zhangsan1", "88888", "张三1", 20, "test1@itcast.cn1"));
  20. users.add(new User(3L, "zhangsan2", "77777", "张三2", 23, "test1@itcast.cn2"));
  21. users.add(new User(4L, "zhangsan3", "66666", "张三3", 24, "test1@itcast.cn3"));
  22. users.add(new User(5L, "zhangsan4", "55555", "张三4", 28, "test1@itcast.cn4"));
  23. users.add(new User(7L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  24. users.add(new User(8L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  25. users.add(new User(7L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  26. users.add(new User(10L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  27. users.add(new User(11L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  28. users.add(new User(12L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  29. users.add(new User(13L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  30. users.add(new User(14L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  31. users.add(new User(15L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  32. List<Map<String,Object>> empList = new ArrayList<>();//必须是List<Map>型几个的数据才可以显示出来
  33. for (int i = 0; i < users.size(); i++) {
  34. Map<String, Object> map = new HashMap<>();
  35. map.put("id",users.get(i).getId());
  36. map.put("userName",users.get(i).getUserName());
  37. map.put("password",users.get(i).getPassword());
  38. map.put("name",users.get(i).getName());
  39. map.put("age",users.get(i).getAge());
  40. map.put("mail",users.get(i).getMail());
  41. empList.add(map);
  42. }
  43. Map<String,Object> empList1 = new HashMap<>();
  44. empList1.put("empList",empList);//放入word表格中需要遍历的集合数据,键名“empList”
  45. String content = "测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!测试!!!\n ";
  46. empList1.put("content",content);
  47. // 模板文件地址
  48. String filePath = "D:\\poi\\wordEasyTem.docx";
  49. // 读取模板后保存生成word的地址
  50. String outPath = "D:\\poi\\easyWordTest.docx";
  51. try {
  52. XWPFDocument doc = WordExportUtil.exportWord07(filePath,empList1);//easypoi自带类与方法,(模板地址,模板所需map)
  53. XWPFDocument doc1 = WordExportUtil.exportWord07(filePath,empList1);//合成所需的另一个虚拟word
  54. List<XWPFDocument> wordList = new ArrayList<>();//需合并时创建的集合
  55. wordList.add(doc);//把所有虚拟word加入集合,以便调用合并方法
  56. wordList.add(doc1);
  57. XWPFDocument xwpfDocument = mergeWord(wordList);//调用word合并方法
  58. File file = new File(outPath);
  59. if (file.exists()) {
  60. file.delete();
  61. }
  62. FileOutputStream out = new FileOutputStream(file);
  63. xwpfDocument.write(out);//将生成的模板数据写入word文件,如果不用合并此处直接doc.即可
  64. out.flush();
  65. out.close();
  66. xwpfDocument.close();//如果不用合并此处直接doc.即可
  67. } catch (Exception e) {
  68. e.printStackTrace();
  69. }
  70. }

word合并工具方法

  1. /**
  2. * word文件合并
  3. * @param wordList
  4. * @return
  5. * @throws Exception
  6. */
  7. public static XWPFDocument mergeWord(List<XWPFDocument> wordList) throws Exception{
  8. if (CollectionUtils.isEmpty(wordList)) {
  9. throw new RuntimeException("待合并的word文档list为空");
  10. }
  11. XWPFDocument doc = wordList.get(0);
  12. int size = wordList.size();
  13. if (size > 1) {
  14. doc.createParagraph().setPageBreak(true);
  15. for (int i = 1; i < size; i++) {
  16. // 从第二个word开始合并
  17. XWPFDocument nextPageDoc = wordList.get(i);
  18. // 最后一页不需要设置分页符
  19. if (i != (size-1)) {
  20. nextPageDoc.createParagraph().setPageBreak(true);
  21. }
  22. appendBody(doc, nextPageDoc);
  23. }
  24. }
  25. return doc;
  26. }
  27. private static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception {
  28. CTBody src1Body = src.getDocument().getBody();
  29. CTBody src2Body = append.getDocument().getBody();
  30. List<XWPFPictureData> allPictures = append.getAllPictures();
  31. // 记录图片合并前及合并后的ID
  32. Map<String,String> map = new HashMap<>();
  33. for (XWPFPictureData picture : allPictures) {
  34. String before = append.getRelationId(picture);
  35. //将原文档中的图片加入到目标文档中
  36. String after = src.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
  37. map.put(before, after);
  38. }
  39. appendBody(src1Body, src2Body,map);
  40. }
  41. private static void appendBody(CTBody src, CTBody append,Map<String,String> map) throws Exception {
  42. XmlOptions optionsOuter = new XmlOptions();
  43. optionsOuter.setSaveOuter();
  44. String appendString = append.xmlText(optionsOuter);
  45. String srcString = src.xmlText();
  46. String prefix = srcString.substring(0,srcString.indexOf(">")+1);
  47. String mainPart = srcString.substring(srcString.indexOf(">")+1,srcString.lastIndexOf("<"));
  48. String sufix = srcString.substring( srcString.lastIndexOf("<") );
  49. String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));
  50. if (map != null && !map.isEmpty()) {
  51. //对xml字符串中图片ID进行替换
  52. for (Map.Entry<String, String> set : map.entrySet()) {
  53. addPart = addPart.replace(set.getKey(), set.getValue());
  54. }
  55. }
  56. //将两个文档的xml内容进行拼接
  57. CTBody makeBody = CTBody.Factory.parse(prefix+mainPart+addPart+sufix);
  58. src.set(makeBody);
  59. }

注意:方法来源于网络,该合并方法有时会使生成的word报数据恢复,我之后多合并了几个就没有出现这种情况

三、生成excel

1、使用Apache poi 手动生成一个简单的excel

(1)导入依赖

  1. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi</artifactId>
  4. <version>4.1.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.poi</groupId>
  8. <artifactId>poi-ooxml</artifactId>
  9. <version>4.1.2</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.deepoove</groupId>
  13. <artifactId>poi-tl</artifactId>
  14. <version>1.10.0</version>
  15. </dependency>

(2)代码示例

  1. import cn.itcast.mp.pojo.User;
  2. import org.apache.poi.ss.usermodel.*;
  3. import org.apache.poi.ss.util.CellRangeAddress;
  4. import org.apache.poi.xssf.usermodel.XSSFSheet;
  5. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  6. import java.io.File;
  7. import java.io.FileNotFoundException;
  8. import java.io.FileOutputStream;
  9. import java.io.IOException;
  10. import java.text.SimpleDateFormat;
  11. import java.util.ArrayList;
  12. import java.util.Date;
  13. import java.util.List;
  14. public static void createExcel(){
  15. List<User> users = new ArrayList<>();//先造点数据
  16. users.add(new User(1L, "zhangsan", "99999", "张三", 25, "test1@itcast.cn"));
  17. users.add(new User(2L, "zhangsan1", "88888", "张三1", 20, "test1@itcast.cn1"));
  18. users.add(new User(3L, "zhangsan2", "77777", "张三2", 23, "test1@itcast.cn2"));
  19. users.add(new User(4L, "zhangsan3", "66666", "张三3", 24, "test1@itcast.cn3"));
  20. users.add(new User(5L, "zhangsan4", "55555", "张三4", 28, "test1@itcast.cn4"));
  21. users.add(new User(6L, "zhangsan5", "44444", "张三5", 30, "test1@itcast.cn5"));
  22. XSSFWorkbook workbook = new XSSFWorkbook();//Apache poi创建excel对象,相当于创建一个虚拟的excel
  23. XSSFSheet sheet = workbook.createSheet("sheet1");//创建一个sheet页,括号内为sheet页名字
  24. sheet.addMergedRegion(new CellRangeAddress(0,0,5,6));//合并单元格 范围:(firstRow,lastRow,firstCol,lastCol),注意行列计算均从0开始
  25. CellStyle cellStyle = workbook.createCellStyle();//设置单元格样式
  26. cellStyle.setBorderBottom(BorderStyle.THIN);//设置单元格样式为黑色实线
  27. cellStyle.setBorderLeft(BorderStyle.THIN);
  28. cellStyle.setBorderRight(BorderStyle.THIN);
  29. cellStyle.setBorderTop(BorderStyle.THIN);
  30. Font font = workbook.createFont();//设置字体样式
  31. font.setFontName("宋体");//字体样式
  32. font.setBold(true);//字体加粗
  33. font.setFontHeightInPoints((short) 12);
  34. cellStyle.setFont(font);
  35. Row row = sheet.createRow(0);//设置表头,获取第一行
  36. row.createCell(0).setCellValue("id");//createRow获取行,createCell获取列,setCellValue,放值
  37. row.createCell(1).setCellValue("userName");
  38. row.createCell(2).setCellValue("password");
  39. row.createCell(3).setCellValue("name");
  40. row.createCell(4).setCellValue("age");
  41. row.createCell(5).setCellValue("mail");
  42. for (int i = 0; i < users.size(); i++) {
  43. Row row1 = sheet.createRow(i+1);
  44. row1.createCell(0).setCellValue(users.get(i).getId());
  45. row1.createCell(1).setCellValue(users.get(i).getUserName());
  46. row1.createCell(2).setCellValue(users.get(i).getPassword());
  47. row1.createCell(3).setCellValue(users.get(i).getName());
  48. row1.createCell(4).setCellValue(users.get(i).getAge());
  49. row1.createCell(5).setCellValue(users.get(i).getMail());
  50. sheet.addMergedRegion(new CellRangeAddress(i+1,i+1,5,6));//合并数据中的单元格
  51. }
  52. String path = "D:\\poi\\excel\\";//生成文件
  53. //判断路径是否存在,否则生成
  54. File file = new File(path);
  55. if (!file.exists()){
  56. file.mkdirs();
  57. }
  58. String fileName = new SimpleDateFormat("yyyy年MM月dd日hhmmssSS").format(new Date() ) + "测试Excel"+".xlsx";
  59. try {
  60. FileOutputStream fileOutputStream = new FileOutputStream(path + fileName);
  61. workbook.write(fileOutputStream);//excel写进文件里
  62. fileOutputStream.close();
  63. } catch (FileNotFoundException e) {
  64. e.printStackTrace();
  65. } catch (IOException e) {
  66. e.printStackTrace();
  67. }
  68. }

2、使用easyexcel按模板生成excel

(1)导入依赖

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>easyexcel</artifactId>
  4. <version>3.0.5</version>
  5. </dependency>

(2)模板样式

 

(3)代码示例

  1. import com.alibaba.excel.EasyExcel;
  2. import com.alibaba.excel.ExcelWriter;
  3. import com.alibaba.excel.enums.WriteDirectionEnum;
  4. import com.alibaba.excel.write.metadata.WriteSheet;
  5. import com.alibaba.excel.write.metadata.fill.FillConfig;
  6. import com.alibaba.excel.write.metadata.fill.FillWrapper;
  7. import java.util.ArrayList;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. import java.util.Map;
  11. public class CreateExcel01 {
  12. public static void main(String[] args) {
  13. List<Map<String,Object>> events = new ArrayList<>();
  14. for (int i = 0; i < 3; i++) {//造点数据
  15. Map<String,Object> map = new HashMap<>();
  16. map.put("index",i+1);
  17. map.put("sys","windows");
  18. map.put("content","测试!测试!测试!测试!测试!测试!测试!测试!");
  19. map.put("time","2022-9-5");
  20. events.add(map);
  21. }
  22. String filePath = "D:\\poi\\zhyw\\excelTest.xlsx";//生成Excel路径
  23. String templatePath = "D:\\poi\\zhyw\\weekTem.xlsx";//模板路径
  24. ExcelWriter excelWriter = EasyExcel.write(filePath).withTemplate(templatePath).build();//easyexcel创建一个虚拟的excel
  25. WriteSheet writeSheet = EasyExcel.writerSheet().build(); // 每次都会重新生成新的一行,而不是使用下面的空行
  26. FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.VERTICAL).forceNewRow(Boolean.TRUE).build();//占位符替换
  27. Map<String, Object> map = new HashMap<>();// 填充数据
  28. map.put("name", "张三");
  29. excelWriter.fill(map, writeSheet);
  30. excelWriter.fill(new FillWrapper("data01", events), fillConfig, writeSheet);//要遍历的数据设置
  31. excelWriter.fill(new FillWrapper("data02", events), fillConfig, writeSheet);//同一个sheet页的不同表中要遍历的数据
  32. excelWriter.finish();// 关闭流
  33. }
  34. }

 3、使用jxls 1.0.6 按模板生成excel

(1)导入依赖

  1. <dependency>
  2. <groupId>net.sf.jxls</groupId>
  3. <artifactId>jxls-core</artifactId>
  4. <version>1.0.6</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.poi</groupId>
  8. <artifactId>poi</artifactId>
  9. <!-- <version>4.1.0</version>此处用4.1.0我会报冲突-->
  10. <version>3.16</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.apache.poi</groupId>
  14. <artifactId>poi-ooxml</artifactId>
  15. <!-- <version>4.1.0</version>-->
  16. <version>3.16</version>
  17. </dependency>

(2)模板样式及说明 

本来循环显示数据表格在设置模板时需要加<foreach>标签,但是我在之前带有合并的表格中加了<foreach>会报无法合并的错误,试了一下,不使用<foreach>也可以循环生成数据

(3)代码示例

  1. import com.jxdinfo.mobile.report.service.IReportService;
  2. import net.sf.jxls.transformer.XLSTransformer;
  3. import org.apache.poi.ss.usermodel.Workbook;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.core.io.ClassPathResource;
  6. import org.springframework.core.io.Resource;
  7. import org.springframework.stereotype.Service;
  8. import java.io.*;
  9. import java.time.LocalDateTime;
  10. import java.time.format.DateTimeFormatter;
  11. import java.util.HashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14. @Service
  15. public class CreateRunInfoWeekExcel {
  16. @Autowired
  17. private IReportService reportService;
  18. public void createRunInfoWeekExcel() {//我所用的数据处理
  19. List<Map<String, Object>> weekRunInfo = reportService.getWeekRunInfo();
  20. DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
  21. String currentTime = LocalDateTime.now().format(dateTimeFormatter);
  22. Map<String,Object> map = new HashMap<>();
  23. for (int i = 0; i < weekRunInfo.size(); i++) {
  24. String sysName = (String) weekRunInfo.get(i).get("sysName");
  25. map = weekRunInfo.get(i);
  26. String fileName = currentTime + sysName + "周运行情况";
  27. createWeekExcelUtil(fileName,map);//调用生成excel方法
  28. }
  29. }
  30. public void createWeekExcelUtil(String fileName,Map<String,Object> map) {//生成excel主要在这里
  31. try {
  32. String filePath = "D:\\poi\\zhyw\\Test01\\"+fileName+".xlsx";// 生成Excel路径
  33. Resource resource = new ClassPathResource("templates/RunInfoWeek01.xlsx");//获取resource文件下的模板路径
  34. String templatePath = resource.getFile().getPath();
  35. //String templatePath = "D:\\poi\\zhyw\\Test01\\RunInfoWeek01.xlsx";//本地模板路径
  36. File file = new File(templatePath);
  37. InputStream inputStream = new FileInputStream(file);//使用输入流读取模板文件
  38. XLSTransformer xlsTransformer = new XLSTransformer();//创建jxls的XLSTransformer对象
  39. Workbook workbook = xlsTransformer.transformXLS(inputStream,map);//生成一个按模板生成的虚拟excel,(模板输入流,占位替换所需map)
  40. OutputStream os = new BufferedOutputStream(new FileOutputStream(filePath));//输出流输出一个备用excel
  41. workbook.write(os);//把之前生成好的模板文件写入流输出的备用excel
  42. inputStream.close();//关闭资源
  43. os.flush();
  44. os.close();
  45. } catch (Exception e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. }

4、使用jxls 2.10.0 按模板生成excel(有条件还是使用新版好,生成excel合并格式也都完整,老版的合并单元格还是有问题需要自己调整)

(1)导入依赖

  1. <dependency>
  2. <groupId>org.jxls</groupId>
  3. <artifactId>jxls</artifactId>
  4. <version>2.10.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.jxls</groupId>
  8. <artifactId>jxls-poi</artifactId>
  9. <version>2.10.0</version>
  10. </dependency>

(2)模板样式

 

 

红色三角就是在excel里加批注,右键单元格就有

(3)模板说明

  • 普通占位符 ${xxx}

  • 循环标签 jx:each(items="循环数据的键" var="遍历时用的对象" lastCell="循环标签这一行 最后一列最后一行")

  • 在最开始标题头那里添加注释 jx:area(lastCell="整个表格的范围")

  • 对于lastCell均只考虑模板先有的行列,并不考虑循环有数据后的行列

(4)代码示例

  1. import org.jxls.common.Context;
  2. import org.jxls.transform.poi.PoiTransformer;
  3. import org.jxls.util.JxlsHelper;
  4. import java.io.*;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. public class JxlsCreateExcel {
  10. public static void main(String[] args) {
  11. List<Map<String, Object>> events = new ArrayList<>();
  12. for (int i = 0; i < 3; i++) {//造点数据
  13. Map<String, Object> map = new HashMap<>();
  14. map.put("index", i + 1);
  15. map.put("sys", "windows");
  16. map.put("content", "测试!测试!测试!测试!测试!测试!测试!测试!");
  17. map.put("time", "2022-9-5");
  18. events.add(map);
  19. }
  20. String filePath = "D:\\poi\\zhyw\\jxlsExcelTest.xlsx";//生成Excel路径
  21. String templatePath = "D:\\poi\\zhyw\\weekTem04.xlsx";//模板路径
  22. File file = new File(templatePath);
  23. try (InputStream is = new FileInputStream(file)) {
  24. try (OutputStream os = new FileOutputStream(filePath)) {
  25. Context context = new Context();//jxls 2.10.0自带的类很像一个map
  26. context.putVar("name","李四");
  27. context.putVar("data01",events);
  28. context.putVar("data02",events);
  29. context.putVar("data03",events);
  30. context.putVar("data04",events);
  31. JxlsHelper.getInstance().processTemplate(is, os, context);//jxls 2.10.0自带的辅助类(模板流,生成文件流,占位符map)
  32. }
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/606868
推荐阅读
相关标签
  

闽ICP备14008679号