数据写入excel
- 使用Apeach POI实现 引入依赖
<!-- excel 文件导出-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
- 引入OSS依赖
<!-- 阿里云oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.1.0</version>
</dependency>
- 数据库查数据
略。
- 使用工作簿将数据写入字节数组输出流并转为字节数组输入流上传到OSS
package com.muyz.javaheirloom.service.impl;
import com.muyz.javaheirloom.entity.ResponseResult;
import com.muyz.javaheirloom.entity.v1.Employees;
import com.muyz.javaheirloom.mapper.v1.EmployeesMapper;
import com.muyz.javaheirloom.service.EmployeesService;
import com.muyz.javaheirloom.service.OssService;
import com.muyz.javaheirloom.utils.AliOssUtil;
import com.muyz.javaheirloom.utils.DocumentUtils;
import com.muyz.javaheirloom.utils.ReflectionUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassDescription:
* @Author: muyuzong
* @Created: 2024/7/23 18:28
*/
@Service
public class EmployeesServiceImpl implements EmployeesService {
@Autowired
EmployeesMapper employeesMapper;
@Autowired
ReflectionUtils reflectionUtils;
@Autowired
AliOssUtil aliOssUtil;
@Autowired
OssService ossService;
@Autowired
DocumentUtils documentUtils;
@Override
public ResponseResult exportListEmpInfoToOss() {
List<Employees> employeesList = employeesMapper.listEmpInfo();
// 获取Emp的字段名作为Excel的表头
List<String> sheetNames = reflectionUtils.getFieldNames(Employees.class);
sheetNames.remove(0); // 第一个属性为序列化ID不需要
// 将emp数据转为excel文件并将其写入字节数组输入流上传到OSS服务器
try (Workbook workbook = new XSSFWorkbook()){
Sheet sheet = workbook.createSheet("员工信息表");
int rowCount = 0;
int columnCount = 0;
// 先写第0行的表头
Row headRow = sheet.createRow(rowCount);
for (String sheetName : sheetNames) {
Cell title = headRow.createCell(columnCount++);
title.setCellValue(sheetName);
title.setCellStyle(documentUtils.setHeaderCellStyle(workbook,true, (short) 12));
}
// 然后逐行写入emp信息
for (Employees emp : employeesList) {
Row row = sheet.createRow(++rowCount);
// 重置为第0列
columnCount = 0;
for (String sheetName : sheetNames) {
// 逐行写入数据
Cell cell = row.createCell(columnCount++);
String fieldValue = reflectionUtils.getFieldValue(emp, sheetName) + "";
cell.setCellValue(fieldValue);
}
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
String fileName = "emp_" + System.currentTimeMillis() + ".xlsx";
aliOssUtil.upload(inputStream,ossService.getObjectNameByPath(fileName));
} catch (IOException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return ResponseResult.ok();
}
}
其中自动注入的工具实现非重点 这里做展示 数据库查询employeesMapper略
package com.muyz.javaheirloom.utils;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.muyz.javaheirloom.entity.ResponseResult;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.io.*;
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
/**
* 文件按流上传
*
* @param inputStream 上传文件的输入流
* @param objectName 填写Object完整路径,不能包含Bucket名称
* @return
*/
public String upload(InputStream inputStream, String objectName) {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 创建PutObject请求。
ossClient.putObject(bucketName, objectName, inputStream);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
//文件访问路径规则 https://BucketName.Endpoint/ObjectName
StringBuilder stringBuilder = new StringBuilder("https://");
stringBuilder
.append(bucketName)
.append(".")
.append(endpoint)
.append("/")
.append(objectName);
log.info("文件上传到:{}", stringBuilder.toString());
return stringBuilder.toString();
}
/**
* 下载OSS服务器文件到本地
* @param filePath
* @param objectName
* @return
*/
public ResponseResult download(String filePath, String objectName) {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
File file = new File(filePath);
if (!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
try {
// 下载Object到本地文件,并保存到指定的本地路径中。如果指定的本地文件存在会覆盖,不存在则新建。
// 如果未指定本地路径,则下载后的文件默认保存到示例程序所属项目对应本地路径中。
ossClient.getObject(new GetObjectRequest(bucketName, objectName), file);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
throw new OSSException("AliOssUtil download err {}", oe);
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
throw new OSSException("AliOssUtil download err {}", ce);
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return ResponseResult.ok();
}
}
package com.muyz.javaheirloom.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Component;
/**
* @ClassDescription:
* @Author: muyuzong
* @Created: 2024/7/24 14:29
*/
@Data
@AllArgsConstructor
@Slf4j
@Component
public class DocumentUtils {
/**
* 创建表头样式
* 默认居中
* @param workbook
* @param isBold 设置字体加粗
* @param fontSize 设置字体大小
* @return
*/
public CellStyle setHeaderCellStyle(Workbook workbook, boolean isBold, Short fontSize) {
CellStyle headerCellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(isBold); // 设置字体加粗
font.setFontHeightInPoints(fontSize); // 设置字体大小
headerCellStyle.setFont(font);
headerCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 设置背景色
headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 设置填充模式
headerCellStyle.setAlignment(HorizontalAlignment.CENTER); // 设置水平居中
// 添加边框样式
headerCellStyle.setBorderTop(BorderStyle.THIN);
headerCellStyle.setBorderBottom(BorderStyle.THIN);
headerCellStyle.setBorderLeft(BorderStyle.THIN);
headerCellStyle.setBorderRight(BorderStyle.THIN);
return headerCellStyle;
}
}
package com.muyz.javaheirloom.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassDescription:
* @Author: muyuzong
* @Created: 2024/7/24 14:14
*/
@Data
@AllArgsConstructor
@Slf4j
@Component
public class ReflectionUtils {
/**
* 获取类的字段名
* @param clazz
* @return
*/
public List<String> getFieldNames(Class<?> clazz) {
Field[] fields = clazz.getDeclaredFields();
List<String> fieldNames = new ArrayList<>();
for (Field field : fields) {
fieldNames.add(field.getName());
}
return fieldNames;
}
/**
* 通过类的字段名获取对应的值
* @param obj
* @param fieldName
* @return
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public Object getFieldValue(Object obj, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(obj);
}
}