阅读 2268

Java操作Excel之EasyExcel、标题、背景色设置

Java操作Excel之EasyExcel、标题、背景色设置

首先不管是学习或者是了解什么技术都要先去看下官方文档

https://alibaba-easyexcel.github.io/index.html


1.import maven depend(导入项目依赖)

<dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>easyexcel</artifactId>

            <version>2.2.6</version>

        </dependency>

1

2

3

4

5

2.Official website case operation(对官网的Demo进行运行)

package com.alibaba.easyexcel.test.demo.read;


import java.io.File;

import java.util.List;

import java.util.Map;


import org.junit.Ignore;

import org.junit.Test;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;


import com.alibaba.easyexcel.test.util.TestFileUtil;

import com.alibaba.excel.EasyExcel;

import com.alibaba.excel.ExcelReader;

import com.alibaba.excel.annotation.ExcelProperty;

import com.alibaba.excel.annotation.format.DateTimeFormat;

import com.alibaba.excel.annotation.format.NumberFormat;

import com.alibaba.excel.converters.DefaultConverterLoader;

import com.alibaba.excel.enums.CellExtraTypeEnum;

import com.alibaba.excel.read.metadata.ReadSheet;

import com.alibaba.fastjson.JSON;


/**

 * 读的常见写法

 *

 * @author Jiaju Zhuang

 */

@Ignore

public class ReadTest {


    private static final Logger LOGGER = LoggerFactory.getLogger(ReadTest.class);


    /**

     * 最简单的读

     * <p>

     * 1. 创建excel对应的实体对象 参照{@link DemoData}

     * <p>

     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}

     * <p>

     * 3. 直接读即可

     */

    @Test

    public void simpleRead() {

        // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去

        // 写法1:

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭

        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();


        // 写法2:

        fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        ExcelReader excelReader = null;

        try {

            excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build();

            ReadSheet readSheet = EasyExcel.readSheet(0).build();

            excelReader.read(readSheet);

        } finally {

            if (excelReader != null) {

                // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的

                excelReader.finish();

            }

        }

    }


    /**

     * 指定列的下标或者列名

     *

     * <p>

     * 1. 创建excel对应的实体对象,并使用{@link ExcelProperty}注解. 参照{@link IndexOrNameData}

     * <p>

     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link IndexOrNameDataListener}

     * <p>

     * 3. 直接读即可

     */

    @Test

    public void indexOrNameRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 这里默认读取第一个sheet

        EasyExcel.read(fileName, IndexOrNameData.class, new IndexOrNameDataListener()).sheet().doRead();

    }


    /**

     * 读多个或者全部sheet,这里注意一个sheet不能读取多次,多次读取需要重新读取文件

     * <p>

     * 1. 创建excel对应的实体对象 参照{@link DemoData}

     * <p>

     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}

     * <p>

     * 3. 直接读即可

     */

    @Test

    public void repeatedRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 读取全部sheet

        // 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写

        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();


        // 读取部分sheet

        fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        ExcelReader excelReader = null;

        try {

            excelReader = EasyExcel.read(fileName).build();


            // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener

            ReadSheet readSheet1 =

                EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();

            ReadSheet readSheet2 =

                EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();

            // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能

            excelReader.read(readSheet1, readSheet2);

        } finally {

            if (excelReader != null) {

                // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的

                excelReader.finish();

            }

        }

    }


    /**

     * 日期、数字或者自定义格式转换

     * <p>

     * 默认读的转换器{@link DefaultConverterLoader#loadDefaultReadConverter()}

     * <p>

     * 1. 创建excel对应的实体对象 参照{@link ConverterData}.里面可以使用注解{@link DateTimeFormat}、{@link NumberFormat}或者自定义注解

     * <p>

     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link ConverterDataListener}

     * <p>

     * 3. 直接读即可

     */

    @Test

    public void converterRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet

        EasyExcel.read(fileName, ConverterData.class, new ConverterDataListener())

            // 这里注意 我们也可以registerConverter来指定自定义转换器, 但是这个转换变成全局了, 所有java为string,excel为string的都会用这个转换器。

            // 如果就想单个字段使用请使用@ExcelProperty 指定converter

            // .registerConverter(new CustomStringStringConverter())

            // 读取sheet

            .sheet().doRead();

    }


    /**

     * 多行头

     *

     * <p>

     * 1. 创建excel对应的实体对象 参照{@link DemoData}

     * <p>

     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}

     * <p>

     * 3. 设置headRowNumber参数,然后读。 这里要注意headRowNumber如果不指定, 会根据你传入的class的{@link ExcelProperty#value()}里面的表头的数量来决定行数,

     * 如果不传入class则默认为1.当然你指定了headRowNumber不管是否传入class都是以你传入的为准。

     */

    @Test

    public void complexHeaderRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet

        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet()

            // 这里可以设置1,因为头就是一行。如果多行头,可以设置其他值。不传入也可以,因为默认会根据DemoData 来解析,他没有指定头,也就是默认1行

            .headRowNumber(1).doRead();

    }


    /**

     * 读取表头数据

     *

     * <p>

     * 1. 创建excel对应的实体对象 参照{@link DemoData}

     * <p>

     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoHeadDataListener}

     * <p>

     * 3. 直接读即可

     */

    @Test

    public void headerRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet

        EasyExcel.read(fileName, DemoData.class, new DemoHeadDataListener()).sheet().doRead();

    }


    /**

     * 额外信息(批注、超链接、合并单元格信息读取)

     * <p>

     * 由于是流式读取,没法在读取到单元格数据的时候直接读取到额外信息,所以只能最后通知哪些单元格有哪些额外信息

     *

     * <p>

     * 1. 创建excel对应的实体对象 参照{@link DemoExtraData}

     * <p>

     * 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoExtraListener}

     * <p>

     * 3. 直接读即可

     *

     * @since 2.2.0-beat1

     */

    @Test

    public void extraRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "extra.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet

        EasyExcel.read(fileName, DemoExtraData.class, new DemoExtraListener())

            // 需要读取批注 默认不读取

            .extraRead(CellExtraTypeEnum.COMMENT)

            // 需要读取超链接 默认不读取

            .extraRead(CellExtraTypeEnum.HYPERLINK)

            // 需要读取合并单元格信息 默认不读取

            .extraRead(CellExtraTypeEnum.MERGE).sheet().doRead();

    }


    /**

     * 读取公式和单元格类型

     *

     * <p>

     * 1. 创建excel对应的实体对象 参照{@link CellDataReadDemoData}

     * <p>

     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoHeadDataListener}

     * <p>

     * 3. 直接读即可

     *

     * @since 2.2.0-beat1

     */

    @Test

    public void cellDataRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "cellDataDemo.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet

        EasyExcel.read(fileName, CellDataReadDemoData.class, new CellDataDemoHeadDataListener()).sheet().doRead();

    }


    /**

     * 数据转换等异常处理

     *

     * <p>

     * 1. 创建excel对应的实体对象 参照{@link ExceptionDemoData}

     * <p>

     * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoExceptionListener}

     * <p>

     * 3. 直接读即可

     */

    @Test

    public void exceptionRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet

        EasyExcel.read(fileName, ExceptionDemoData.class, new DemoExceptionListener()).sheet().doRead();

    }


    /**

     * 同步的返回,不推荐使用,如果数据量大会把数据放到内存里面

     */

    @Test

    public void synchronousRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 同步读取会自动finish

        List<DemoData> list = EasyExcel.read(fileName).head(DemoData.class).sheet().doReadSync();

        for (DemoData data : list) {

            LOGGER.info("读取到数据:{}", JSON.toJSONString(data));

        }


        // 这里 也可以不指定class,返回一个list,然后读取第一个sheet 同步读取会自动finish

        List<Map<Integer, String>> listMap = EasyExcel.read(fileName).sheet().doReadSync();

        for (Map<Integer, String> data : listMap) {

            // 返回每条数据的键值对 表示所在的列 和所在列的值

            LOGGER.info("读取到数据:{}", JSON.toJSONString(data));

        }

    }


    /**

     * 不创建对象的读

     */

    @Test

    public void noModelRead() {

        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";

        // 这里 只要,然后读取第一个sheet 同步读取会自动finish

        EasyExcel.read(fileName, new NoModelDataListener()).sheet().doRead();

    }

}

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

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

3.Specific use in the project(项目中的具体使用)

3.1 写入

3.1.1 写入实体类的创建

package com.backend.pojo.vo;


import com.alibaba.excel.annotation.ExcelProperty;

import com.fasterxml.jackson.annotation.JsonFormat;

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

import org.springframework.format.annotation.DateTimeFormat;


import javax.persistence.*;

import java.io.Serializable;

import java.util.Date;


/**

 * @author ZhangSan_Plus

 * @version 1.0

 * @className SecurityCertVo

 * @description TODO

 * @date 2021/4/19 11:27

 **/

@Data

@AllArgsConstructor

@NoArgsConstructor

public class SecurityCertVo implements Serializable {

    @ExcelProperty({"加密保证书查询详情","公司名称"})

    private String companyName;

    @ExcelProperty({"加密保证书查询详情","公司网址"})

    private String website;

    @ExcelProperty({"加密保证书查询详情","版本"})

    private String version;

    @ExcelProperty({"加密保证书查询详情","类型"})

    private String certificateType;

    @ExcelProperty({"加密保证书查询详情","品牌"})

    private String certificateBrand;

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")

    @DateTimeFormat(pattern = "yyyy-MM-dd")

    @ExcelProperty({"加密保证书查询详情","签发时间"})

    private Date issueDate;

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")

    @DateTimeFormat(pattern = "yyyy-MM-dd")

    @ExcelProperty({"加密保证书查询详情","到期时间"})

    private Date deadlineDate;

 }

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

3.1.2 编写写入的具体实现

public class SecurityCertExport{

private static final String CERT_TITLE="数据导出SHEET名称";

public void export(HttpServletResponse response) {

        List<SecurityCertVo> list = Lists.newArrayList();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Date date = new Date();

        String uuidStr = UUID.randomUUID().toString().replaceAll("-", "");

        //uuid年月日data

        String filename = uuidStr + simpleDateFormat.format(date) + "data";

        response.setContentType("application/vnd.ms-excel");

        response.setCharacterEncoding("utf-8");

        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        response.setHeader("Content-Disposition", "attachment;filename=" + filename + ".xlsx");

        ExcelWriter excelWriter = null;

        try {

            excelWriter = EasyExcel.write(response.getOutputStream()).build();

            WriteSheet sheet = EasyExcel.writerSheet(0, CERT_TITLE).head(SecurityCertVo.class).build();

            excelWriter.write(list, sheet);

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            excelWriter.finish();

        }

    }

}

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

导出结果如下图所示


————————————————

版权声明:本文为CSDN博主「CSS最难的编程语言」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_43565087/article/details/115973837


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐