导出

导出excel

首先了解下Jakarta POI HSSF API常用组件和样式

类名    作用
HSSFWorkbook    excel的文档对象
HSSFSheet    excel的表单
HSSFRow    excel的行
HSSFCell    excel的格子单元
HSSFFont    excel字体
HSSFDataFormat    日期格式
HSSFHeader    sheet头
HSSFFooter    sheet尾(只有打印的时候才能看到效果)
HSSFCellStyle    cell样式
一、导入poi所需要的jar包
这两个jar包的版本一定要一致,不然可能会报异常java.lang.NoClassDefFoundError: org/apache/poi/UnsupportedFileFormatException

<dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.11</version>
</dependency>
<dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.11</version>
</dependency>

二、编写导出excel的工具类

1、HSSFWorkbook创建Excel文件对象
2、HSSFWorkbook对象返回或者创建Sheet对象
3、Sheet对象返回行对象,用行对象得到Cell对象
4、对Cell对象进行读写操作

public class ExcelUtil {
    /**
     * 导出excel
     * @param title  导出表的标题
     * @param rowsName 导出表的列名
     * @param dataList  需要导出的数据
     * @param fileName  生成excel文件的文件名
     * @param response
     */
    public void exportExcel(String title,String[] rowsName,List<Object[]> dataList,String fileName,HttpServletResponse response) throws Exception{
        OutputStream output = response.getOutputStream();
        response.reset();
        response.setHeader("Content-disposition", "attachment; filename="+fileName);
        response.setContentType("application/msexcel");
        this.export(title,rowsName,dataList,fileName,output);
        this.close(output);

    }


    /**
     * 导出数据
     * @param title 导出表的标题
     * @param rowName 导出表的列名
     * @param dataList 需要导出的数据
     * @param fileName 生成excel文件的文件名
     * @param out
     * @throws Exception
     */
    private void export(String title,String[] rowName,List<Object[]> dataList,String fileName,OutputStream out) throws Exception {
        try {
            // 创建工作簿对象
            HSSFWorkbook workbook = new HSSFWorkbook();
            // 创建工作表
            HSSFSheet sheet = workbook.createSheet(title);
            // 产生表格标题行
            HSSFRow rowm = sheet.createRow(0);
            //创建表格标题列(需要的可以放开,这里不使用标题列)
            //HSSFCell cellTiltle = rowm.createCell(0);
            // sheet样式定义;    getColumnTopStyle();    getStyle()均为自定义方法 --在下面,可扩展
            // 获取列头样式对象
            HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);
            // 获取单元格样式对象
            HSSFCellStyle style = this.getStyle(workbook);
            //合并表格标题行,合并列数为列名的长度,第一个0为起始行号,第二个1为终止行号,第三个0为起始列好,第四个参数为终止列号
            //合并单元格(需要的可以放开,这里不合并单元格)
            //sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (rowName.length - 1)));
            //设置标题行样式(需要的可以放开,这里不使用标题列)
            //cellTiltle.setCellStyle(columnTopStyle);
            //设置标题行值(需要的可以放开,这里不使用标题列)
            //cellTiltle.setCellValue(title);
            // 定义所需列数
            int columnNum = rowName.length;
            // 在索引2的位置创建行(最顶端的行开始的第二行)
            HSSFRow rowRowName = sheet.createRow(0);
            // 将列头设置到sheet的单元格中
            for (int n = 0; n < columnNum; n++) {
                // 创建列头对应个数的单元格
                HSSFCell cellRowName = rowRowName.createCell(n);
                // 设置列头单元格的数据类型
                cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING);
                HSSFRichTextString text = new HSSFRichTextString(rowName[n]);
                // 设置列头单元格的值
                cellRowName.setCellValue(text);
                // 设置列头单元格样式
                cellRowName.setCellStyle(columnTopStyle);
            }

            // 将查询出的数据设置到sheet对应的单元格中
            for (int i = 0; i < dataList.size(); i++) {
                Object[] obj = dataList.get(i);
                // 创建所需的行数,排除掉标题行的数量
                HSSFRow row = sheet.createRow(i + 1);
                for (int j = 0; j < obj.length; j++) {
                    // 设置单元格的数据类型
                    HSSFCell cell = null;
                    if (j == 0) {
                        cell = row.createCell(j, HSSFCell.CELL_TYPE_NUMERIC);
                        cell.setCellValue(i + 1);
                    } else {
                        cell = row.createCell(j, HSSFCell.CELL_TYPE_STRING);
                        if (!"".equals(obj[j]) && obj[j] != null) {
                            // 设置单元格的值
                            cell.setCellValue(obj[j].toString());
                        }
                    }
                    // 设置单元格样式
                    cell.setCellStyle(style);
                }
            }

            // 让列宽随着导出的列长自动适应
            for (int colNum = 0; colNum < columnNum; colNum++) {
                int columnWidth = sheet.getColumnWidth(colNum) / 256;
                for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
                    HSSFRow currentRow;
                    // 当前行未被使用过
                    if (sheet.getRow(rowNum) == null) {
                        currentRow = sheet.createRow(rowNum);
                    } else {
                        currentRow = sheet.getRow(rowNum);
                    }
                    if (currentRow.getCell(colNum) != null) {
                        HSSFCell currentCell = currentRow.getCell(colNum);
                        if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                            int length = currentCell.getStringCellValue()
                                    .getBytes().length;
                            if (columnWidth < length) {
                                columnWidth = length;
                            }
                        }
                    }
                }
                if (colNum == 0) {
                    //设置宽度
                    sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
                } else {
                    sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);
                }
            }
            workbook.write(out);
            //文件自定义存放位置(不写默认在下载里,这里不使用)
            //workbook.write(new FileOutputStream(new File("D://test"+".xls")));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 列头单元格样式
     * @param workbook
     * @return
     */
    private HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {

        // 设置字体
        HSSFFont font = workbook.createFont();
        // 设置字体大小
        font.setFontHeightInPoints((short) 11);
        // 字体加粗
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        // 设置字体名字
        font.setFontName("Courier New");
        // 设置样式;
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置底边框;
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        // 设置底边框颜色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        // 设置左边框;
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 设置左边框颜色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        // 设置右边框;
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 设置右边框颜色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        // 设置顶边框;
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 设置顶边框颜色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        // 在样式用应用设置的字体;
        style.setFont(font);
        // 设置自动换行;
        style.setWrapText(false);
        // 设置水平对齐的样式为居中对齐;
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

        return style;

    }

    /**
     * 列数据信息单元格样式
     * @param workbook
     * @return
     */
    private HSSFCellStyle getStyle(HSSFWorkbook workbook) {
        // 设置字体
        HSSFFont font = workbook.createFont();
        // 设置字体大小
        // font.setFontHeightInPoints((short)10);
        // 字体加粗
        // font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        // 设置字体名字
        font.setFontName("Courier New");
        // 设置样式;
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置底边框;
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        // 设置底边框颜色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        // 设置左边框;
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 设置左边框颜色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        // 设置右边框;
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 设置右边框颜色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        // 设置顶边框;
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 设置顶边框颜色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        // 在样式用应用设置的字体;
        style.setFont(font);
        // 设置自动换行;
        style.setWrapText(false);
        // 设置水平对齐的样式为居中对齐;
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        return style;
    }

    /**
     * 关闭输出流
     * @param os
     */
    private void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
三、使用测试

@RequestMapping("exportWordData")
    public void exportExcelData(HttpServletRequest request, HttpServletResponse response){
        // 定义表的标题
        String title = "员工列表一览";
        //定义表的列名
        String[] rowsName = new String[] { "序号", "姓名", "性别", "特长", "学历", "入职时间", "简历", "照片", "部门" };
        List<Object[]> dataList = new ArrayList<Object[]>();
        //定义表的内容第一行
        Object[] objs = new Object[9];
        objs[0] = "测试";
        objs[1] = 11;
        objs[2] = "111";
        objs[3] = "测试";
        objs[4] = "测试";
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String date = df.format(2018-12-24);
        objs[5] = date;
        objs[6] = "测试";
        objs[7] = "测试";
        objs[8] = "测试";
        //定义表的内容第二行
        Object[] objs1 = new Object[9];
        objs1[0] = "测试";
        objs1[1] = 11;
        objs1[2] = "111";
        objs1[3] = "测试";
        objs1[4] = "测试";
        SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
        String date1 = df1.format(2019-12-24);
        objs1[5] = date1;
        objs1[6] = "测试";
        objs1[7] = "测试";
        objs1[8] = "测试";
        dataList.add(objs);
        dataList.add(objs1);
        // 创建ExportExcel对象
        ExcelUtil excelUtil = new ExcelUtil();

        try{
            //生成word文件的文件名
            String fileName= new String("测试excel文档.xlsx".getBytes("UTF-8"),"iso-8859-1");
            excelUtil.exportExcel(title,rowsName,dataList,fileName,response);
            System.out.println(true);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
四、效果展示

导入excel

导入与导出的基本步骤相似,关键要了解要导入excel的结构,比如数据列、读取数据的起始位置等,理解了导出那么导入也就没什么难处了

一、控制层

@PostMapping("/import")
    public boolean addUser(@RequestParam("file") MultipartFile file) {
        boolean a = false;
        String fileName = file.getOriginalFilename();
        try {
            a = userService.batchImport(fileName, file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(a);
        return  a;
    }
1
2
3
4
5
6
7
8
9
10
11
12
二、实现层

boolean batchImport(String fileName, MultipartFile file) throws Exception;

@Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean batchImport(String fileName, MultipartFile file) throws Exception {
        boolean notNull = false;
        List<User> userList = new ArrayList<User>();
        //正则验证上传文件格式
        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            return false;
        }
        boolean isExcel = true;
        if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
            isExcel = false;
        }
        InputStream is = file.getInputStream();
        Workbook wb = WorkbookFactory.create(is);
        Sheet sheet = wb.getSheetAt(0);
        if(sheet!=null){
            notNull = true;
        }
        User user;
        //遍历当前页所有行
        for (int r = 1; r <= sheet.getLastRowNum(); r++) {
            Row row = sheet.getRow(r);
            if (row == null){
                continue;
            }
            user = new User();
            if( row.getCell(0).getCellType() !=1){
                return false;
            }
            String name = row.getCell(0).getStringCellValue();
            if(name == null || name.isEmpty()){
                return false;
            }
            row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
            String phone = row.getCell(1).getStringCellValue();
            if(phone==null || phone.isEmpty()){
                return false;
            }
            String add = row.getCell(2).getStringCellValue();
            if(add==null){
                return false;
            }
            Date date=new Date();
            if(row.getCell(3).getCellType() !=0){
                return false;
            }else{
                date = row.getCell(3).getDateCellValue();
            }
            String des = row.getCell(4).getStringCellValue();
            user.setName(name);
            user.setPhone(phone);
            user.setAddress(add);
            user.setEnrolDate(date);
            user.setDes(des);
            userList.add(user);
        }
        for (User userResord : userList) {
            userDao.addUser(userResord);
            System.out.println(" 插入 "+userResord);
            
        }
        return notNull;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
三、前端传入文件

必须使用post方式传入

<form method="post" enctype="multipart/form-data" action="user/import" >
    <input type="file" name="file"/>
    <input type="submit" value="提交">
</form>
1
2
3
4
四、使用测试


导入功能要根据具体的业务实现,为了方便小伙伴使用我整理了文件读取功能,保存就需要自己实现啦!附上excel读取工具类:

public class ImportExcelUtil {
    /**
     * 获取excel数据
     * 文件后缀只能是xls、xlsx
     *
     * @param inputStream
     * @param fileName
     * @return
     * @throws IOException
     */
    public static List<Map<String, Object>> getExcelData(InputStream inputStream, String fileName) throws IOException {
        Map<String, Object> resultMap = new HashMap<>();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        suffix = suffix.toLowerCase();
        List<String> sheetNameList = new ArrayList<>();
        List<Map<String, Object>> listDataMap = new ArrayList<>();
        if ("xls".equals(suffix)) {
            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
            HSSFSheet sheet = null;
            //获取每个Sheet表
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                sheetNameList.add(workbook.getSheetName(i));
                sheet = workbook.getSheetAt(i);
                List<List<String>> sheetList = new ArrayList<>();
                Map<String, Object> sheetDataMap = new HashMap<>();
                //获取每行
                for (int j = 1; j < sheet.getPhysicalNumberOfRows(); j++) {
                    HSSFRow row = sheet.getRow(j);
                    List<String> rowList = new ArrayList<String>();
                    //获取每个单元格
                    for (int k = 0; k < row.getPhysicalNumberOfCells(); k++) {
                        rowList.add(String.valueOf(row.getCell(k)));
                    }
                    sheetList.add(rowList);
                }
                System.out.println(workbook.getSheetName(i) + "表数据:" + sheetList);
                sheetDataMap.put("sheetName", workbook.getSheetName(i).trim());
                sheetDataMap.put("data", sheetList);
                listDataMap.add(sheetDataMap);
            }
        } else if ("xlsx".equals(suffix)) {
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = null;
            //获取每个Sheet表
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                sheetNameList.add(workbook.getSheetName(i));
                sheet = workbook.getSheetAt(i);
                List<List<String>> sheetList = new ArrayList<>();
                Map<String, Object> sheetDataMap = new HashMap<>();
                //获取每行
                for (int j = 2; j < sheet.getPhysicalNumberOfRows(); j++) {
                    XSSFRow row = sheet.getRow(j);
                    List<String> rowList = new ArrayList<String>();
                    //获取每个单元格
                    for (int k = 0; k < row.getPhysicalNumberOfCells(); k++) {
                        rowList.add(String.valueOf(row.getCell(k)));
                    }
                    sheetList.add(rowList);
                }
                sheetDataMap.put("sheetName", workbook.getSheetName(i).trim());
                sheetDataMap.put("data", sheetList);
                listDataMap.add(sheetDataMap);
            }
            System.out.println("---所有数据:" + listDataMap);
        }
        return listDataMap;
    }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值