需求:根据指定的路径下模版进行解析 将模版上传到指定的文件服务器。
1:将路径下的excel文件进行解析 下载
A:创建excel表格对应的字段注解 ExcelColumn
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelColumn {
int index() default -1; // 列的索引,从0开始
String name() default ""; // 列名,可以与Excel中的标题对应
}
B:建立一个excel映射的实体对象
@ExcelColumn(index = 1, name = "A")
private String A;
@ExcelColumn(index = 2, name = "B")
private String B;
上述的属性A B的index对应excel的标题头的第几列的字段值
C:为了方便后续解析任意的excel文件 故创建一个文件解析工具 ExcelParserUtil.java
/**
* excel解析工具类
*
* @param inputStream
* @param clazz
* @param <T>
* @return
*/
public static <T> List<T> parseExcel(InputStream inputStream, Class<T> clazz) throws Exception {
List<T> result = new ArrayList<>();
List<String> failReasonList = new ArrayList<>();
int execRow = 1;
try (Workbook workbook = new XSSFWorkbook(inputStream)) {
Sheet sheet = workbook.getSheetAt(0); //第一个工作表
Row headerRow = sheet.getRow(0); //第一行是标题行
// 读取实体类的字段注解,构建字段名和列索引的映射
Map<String, Integer> fieldIndexMap = new HashMap<>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
ExcelColumn excelColumn = field.getAnnotation(ExcelColumn.class);
if (excelColumn != null && excelColumn.index() >= 0) {
field.setAccessible(true);
fieldIndexMap.put(field.getName(), excelColumn.index());
}
}
// 跳过标题行,从第二行开始解析数据
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
T instance = clazz.getDeclaredConstructor().newInstance();
for (Map.Entry<String, Integer> entry : fieldIndexMap.entrySet()) {
try {
String fieldName = entry.getKey();
int columnIndex = entry.getValue();
Cell cell = row.getCell(columnIndex);
if (cell != null) {
Field field = clazz.getDeclaredField(fieldName);
setFieldValue(instance, field, cell);
}
} catch (Exception e) {
failReasonList.add("第" + execRow + "行解析错误:" + e.getMessage());
}
}
execRow++;
result.add(instance);
}
} catch (Exception e) {
throw new Exception("parseExcel->数据解析错误:", e);
}
if (CollectionUtils.isNotEmpty(failReasonList)) {
throw new Exception(JSON.toJSONString(failReasonList.subList(0, failReasonList.size() > 20 ? 20 : failReasonList.size())));
}
return result;
}
/**
* 方法setFieldValue 主要用于给每个单元格进行设置对应的值。
* @param instance
* @param field
* @param cell
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static void setFieldValue(Object instance, Field field, Cell cell) throws IllegalAccessException, InvocationTargetException {
Class<?> fieldType = field.getType();
field.setAccessible(true);
// 总是将Cell设置为STRING类型,以确保我们可以获取字符串值
cell.setCellType(CellType.STRING);
String cellValue = cell.getStringCellValue();
if (String.class.equals(fieldType)) {
field.set(instance, cell.getStringCellValue());
} else if (Integer.class.equals(fieldType) || int.class.equals(fieldType)) {
field.setInt(instance, Integer.parseInt(cellValue));
} else if (Long.class.equals(fieldType) || long.class.equals(fieldType)) {
field.setLong(instance, Long.parseLong(cellValue));
} else if (Double.class.equals(fieldType) || double.class.equals(fieldType)) {
field.setDouble(instance, Double.parseDouble(cellValue));
} else if (Boolean.class.equals(fieldType) || boolean.class.equals(fieldType)) {
field.setBoolean(instance, Boolean.parseBoolean(cellValue));
} else {
throw new RuntimeException("Unsupported field type: " + fieldType.getName());
}
}
/**
* 指定下载的文件路径 将文件流保存到执行的的位置
*
* @param url
* @param savePath
* @return
*/
public static String download(String url, String savePath) {
InputStream inputStream = null;
FileOutputStream fos = null;
try {
URL u = new URL(url);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
//设置超时间为3秒
conn.setConnectTimeout(HTTP_CONNECT_TIMEOUT);
//防止屏蔽程序抓取而返回403错误
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//得到输入流
inputStream = conn.getInputStream();
//获取自己数组
byte[] getData = readInputStream(inputStream);
File file = new File(savePath);
// 文件保存位置
createDir(file);
fos = new FileOutputStream(file);
fos.write(getData);
} catch (IOException e) {
} finally {
try {
if (fos != null) {
fos.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
}
}
return savePath;
}
/**
* 从输入流中获取字节数组
*
* @param inputStream
* @return
* @throws IOException
*/
private static byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
return bos.toByteArray();
}
/**
* 根据文件创建目录
*
* @param file
*/
public static void createDir(File file) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
}
D:使用上述工具类进行文件的解析和下载功能演练
//下载路径
private static final String downloadUrl = "https://xxx.com.cn/files/";
//模版位置
private static final String templateUrl = "E:/source";
//下载文件存放位置
private static final String saveUrl = "E:/source/downlod";
private static final String handCompany = "1-A.xlsx";
private static final String company = "2-B.xlsx";
private static final String industry = "3-C.xlsx";
public static void main(String[] args) {
ExcelParserUtil parser = new ExcelParserUtil();
try {
File file = new File(templateUrl); // 替换为你的文件路径
File[] files = file.listFiles();
for (File fileItem : files) {
if (fileItem.isFile()) {
InputStream inputStream = new FileInputStream(fileItem);
if (inputStream != null) {
String fileName = fileItem.getName();
List<ExcelEntity> excelEntities = parser.parseExcel(inputStream, ExcelEntity.class);
exec(excelEntities, parser, fileName);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void exec(List<ExcelEntity> entityList, ExcelParserUtil parser, String fileName) {
List<String> list = new ArrayList<>();
// 输出解析结果
System.out.println("解析了数据:" + entityList.size());
for (ExcelEntity entity : entityList) {
//得到解析的文件数据做自己的业务逻辑处理。
String finalUrl = downloadUrl + fileUrl;
//处理投资池证券导入模板文件路径字段
String download = parser.download(finalUrl, saveUrl + File.separator + "新的文件名称");
}
}
2:上传文件到执行服务器
/**
* 上传文件
* @param filePath
* @param typeId
* @return
*/
public static R upload(String filePath, String typeId) {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse httpResponse = null;
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(200000).setSocketTimeout(200000000).build();
HttpPost httpPost = new HttpPost(baseUrl + PREFIX + "/service/files/upload");
httpPost.setConfig(requestConfig);
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
multipartEntityBuilder.setCharset(Charset.forName("UTF-8"));
File file = new File(filePath);
if (FrameStringUtil.isNotEmpty(typeId)) {
multipartEntityBuilder.addPart("typeId", new StringBody(typeId, ContentType.create("text/plain", Consts.UTF_8)));
}
HttpEntity httpEntity = multipartEntityBuilder.build();
httpPost.setEntity(httpEntity);
try {
httpResponse = httpClient.execute(httpPost);
HttpEntity responseEntity = httpResponse.getEntity();
int statusCode= httpResponse.getStatusLine().getStatusCode();
if(statusCode == 200) {
BufferedReader reader = new BufferedReader(new InputStreamReader(responseEntity.getContent()));
StringBuffer buffer = new StringBuffer();
String str = "";
while(FrameStringUtil.isNotEmpty(str = reader.readLine())) {
buffer.append(str);
}
String result = buffer.toString();
R.setBody(result);
R.setSucc();
//post(url, params);
}
httpClient.close();
if(httpResponse != null) {
httpResponse.close();
}
} catch (IOException e) {
e.printStackTrace();
R.setCode(-1001);
R.setMessage("上传文件到文件管理服务失败: " + e.getMessage());
}
return R;
}
3:文件基础相关操作
/**
* 删除指定零时目录下的文件
*
* @param sourceUrl
* @param destinationUrl
* @param fileName
* @return
*/
public static Boolean deleteFilesInDirectory(String tempUrl) {
Boolean delFlag = false;
File directory = new File(tempUrl);
if (directory.exists() && directory.isDirectory()) {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
file.delete();
delFlag = true;
log.info("Deleted file: {}", file.getName());
}
}
} else {
log.info("The directory is empty.....");
delFlag = false;
}
} else {
delFlag = false;
log.info("The directory does not exist or is not a directory.");
}
return delFlag;
}
/**
* 将byte[]转成File
*
* @param sourceUrl
* @param destinationUrl
* @param fileName
* @return
*/
public static File byteToFile(byte[] bytes, String path, String name) throws IOException {
File dir = new File(path);
if (!dir.exists() && !dir.isDirectory()) {//判断文件目录是否存在
dir.mkdirs();
}
File file = new File(path + File.separator + name);
FileOutputStream fout = new FileOutputStream(file);
BufferedOutputStream bout = new BufferedOutputStream(fout);
bout.write(bytes);
return file;
}
/**
* 文件复制转移
*
* @param sourceUrl
* @param destinationUrl
* @param fileName
* @return
*/
public static String copyFile(String sourceUrl, String destinationUrl, String fileName) {
String fileTempUrl = "";
File sourceFile = new File(sourceUrl);
fileTempUrl = destinationUrl + File.separator + fileName;
File destinationFile = new File(fileTempUrl);
try {
FileUtils.copyFile(sourceFile, destinationFile);
log.info("文件复制成功!");
} catch (IOException e) {
log.info("文件复制失败!");
System.out.println("文件复制失败!" + e.getMessage());
}
return fileTempUrl;
}
4:文件相关操作工具类
/**
* 创建指定路径的文件夹[不存在,则创建]
* @param destDirName
*/
public static void createDir(String destDirName) {
File dir = new File(destDirName);
if(dir.exists()) {
LOGGER.info("目录" + destDirName + "已存在!");
} else {
if(!destDirName.endsWith(File.separator)) {
destDirName = destDirName + File.separator;
}
//创建目录
dir.mkdirs();
}
}
/**
* 读取文件[不存在,则创建]
* @param destFileName 文件名
* @return 创建成功返回true,否则返回false
* @throws IOException
*/
public static File readFile(String destFileName) throws IOException {
File file = new File(destFileName);
if (file.exists()) {
//LOGGER.info("目标文件已存在: " + destFileName);
return file;
}
if (!file.getParentFile().exists()) {
if (!file.getParentFile().mkdirs()) {
LOGGER.info("创建目录文件所在的目录失败!");
}
}
//创建目标文件
if (file.createNewFile()) {
LOGGER.info("创建单个文件成功: " + destFileName);
} else {
LOGGER.info("创建单个文件失败: " + destFileName);
}
return file;
}
/**
* 读取文件为byte[]
* @param destFileName
* @return
*/
public static byte[] readFileBytes(String destFileName) {
try {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(destFileName));
int len = bufferedInputStream.available();
byte[] bytes = new byte[len];
int r = bufferedInputStream.read(bytes);
if (len != r) {
bytes = null;
LOGGER.error("读取文件不正确");
}
bufferedInputStream.close();
return bytes;
} catch (FileNotFoundException e) {
LOGGER.error(e.getMessage(), e);
}
catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
return null;
}
/**
* 根据目录获取下面为指定文件名的文件
* @param dir
* @param filename
* @return
*/
public static List<String> getFiles(String dir, String filename) {
List<String> list = new ArrayList<String>();
Map<String, List<String>> map = getDirFile(dir, true);
List<String> allList = map.get("files");
if(allList == null) {
list = new ArrayList<String>();
} else {
for (String string : allList) {
if(string.endsWith(File.separator + filename)) {
list.add(string);
}
}
}
return list;
}
/**
* 获取目录下的文件和文件夹
* @param dir
* @param isRecursion 是否递归,true是 false否
* @return {"files":["文件地址",""],"dirs":["目录地址",""]}
*/
public static Map<String, List<String>> getDirFile(String dir, boolean isRecursion) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
File file = new File(dir);
getDirFileDtl(file, map, isRecursion);
return map;
}
/*
* 获取目录的指定内容
* @param file
* @param map
*/
private static void getDirFileDtl(File file, Map<String, List<String>> map, boolean isRecursion) {
File[] t = file.listFiles();
if(t == null) {
return;
}
for(int i = 0; i < t.length; i++){
//判断文件列表中的对象是否为文件夹对象,如果是则执行tree递归,直到把此文件夹中所有文件输出为止
if(t[i].isDirectory()) {
List<String> dirs = map.get("dirs");
if(dirs == null) {
dirs = new ArrayList<String>();
}
dirs.add(t[i].getAbsolutePath());
//System.out.println(t[i].getAbsolutePath()+"\n");
map.put("dirs", dirs);
if(isRecursion) {
getDirFileDtl(t[i], map, isRecursion);
}
} else{
List<String> files = map.get("files");
if(files == null) {
files = new ArrayList<String>();
}
files.add(t[i].getAbsolutePath());
//System.out.println(t[i].getAbsolutePath()+"\n");
map.put("files", files);
getDirFileDtl(t[i], map, isRecursion);
}
}
}
/**
* 读取http地址的文件到指定位置
* @param url
* @param savePath
* @param saveName
* @return
*/
public static File readFile(String url, String savePath, String saveName) {
try {
//new一个URL对象
URL u = new URL(url);
//打开链接
HttpURLConnection conn = (HttpURLConnection)u.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
//通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readFileBytes(inStream);
//new一个文件对象用来保存图片,默认保存当前工程根目录
createDir(savePath);
File file = new File(savePath + saveName);
if(file.exists()) {
file.delete();
}
file = new File(savePath + saveName);
//创建输出流
FileOutputStream outStream = new FileOutputStream(file);
//写入数据
outStream.write(data);
//关闭输出流
outStream.close();
return file;
} catch (IOException e) {
LOGGER.error("读取异常", e);
}
return null;
}
/**
* 创建ZIP文件
* @param sourcePath 文件或文件夹路径
* @param zipPath 生成的zip文件存在路径(包括文件名)
*/
public static boolean createZip(String sourcePath, String zipPath) {
FileOutputStream fos = null;
ZipOutputStream zos = null;
try {
fos = new FileOutputStream(zipPath);
zos = new ZipOutputStream(fos);
writeZip(new File(sourcePath), "", zos);
} catch (FileNotFoundException e) {
LOGGER.error("创建ZIP文件失败", e);
return false;
} finally {
try {
if (zos != null) {
zos.close();
}
} catch (IOException e) {
LOGGER.error("创建ZIP文件失败",e);
}
}
return true;
}
private static void writeZip(File file, String parentPath, ZipOutputStream zos) {
if(file.exists()){
if(file.isDirectory()){//处理文件夹
parentPath+=file.getName()+File.separator;
File [] files=file.listFiles();
for(File f:files){
writeZip(f, parentPath, zos);
}
}else{
FileInputStream fis=null;
DataInputStream dis=null;
try {
fis=new FileInputStream(file);
dis=new DataInputStream(new BufferedInputStream(fis));
ZipEntry ze = new ZipEntry(parentPath + file.getName());
zos.putNextEntry(ze);
byte [] content=new byte[1024];
int len;
while((len=fis.read(content))!=-1){
zos.write(content,0,len);
zos.flush();
}
} catch (FileNotFoundException e) {
LOGGER.error("创建ZIP文件失败",e);
} catch (IOException e) {
LOGGER.error("创建ZIP文件失败",e);
}finally{
try {
if(dis!=null){
dis.close();
}
}catch(IOException e) {
LOGGER.error("创建ZIP文件失败",e);
}
}
}
}
}
/**
* 公用下载文件<br>
* frame 返回路径和文件名称
* fileName:下载文件的名称
* downloadPath:下载文件的路径
* @param request
* @param response
* @param frame
* @throws IOException
*/
public void download(HttpServletRequest request, HttpServletResponse response,
String fileName, String downloadPath) throws IOException {
response.setContentType("text/html;charset=UTF-8");
try {
request.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
if(FrameStringUtil.isEmpty(fileName) || FrameStringUtil.isEmpty(downloadPath)) {
return;
}
long fileLength = new File(downloadPath).length();
response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"),"iso-8859-1"));
response.setHeader("Content-Length", String.valueOf(fileLength));
bis = new BufferedInputStream(new FileInputStream(downloadPath));
bos = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
bis.close();
bos.close();
}
/**
* @param workbook Excel
* @param sheetName 工作簿名称
* @param cellFieldList 字段列表
* @param rowList 数据列表
* @throws Exception
* @description: 向Excel中写入数据
*/
public static <T> void writeExcel(XSSFWorkbook workbook, String sheetName, List<CellField> cellFieldList, List<T> rowList, Map<String, Object> rowData, int type) {
if (StringUtils.isRealEmpty(sheetName)) {
sheetName = "Sheet1";
}
Sheet sheet = workbook.createSheet(sheetName);
Font boldFont = createFont(workbook, true, "宋体", false, (short) 200);
Font normalFont = createFont(workbook, false, "宋体", false, (short) 200);
try {
// 标题(第一行)
Row titleRow = sheet.createRow(0);
int cellNumber = cellFieldList.size();
for (int i = 0; i < cellNumber; i++) {
CellField cellField = cellFieldList.get(i);
createCell(workbook, titleRow, i, cellField.getName(), CellType.STRING, boldFont);
// 设置单元格宽带
sheet.setColumnWidth(i, 256 * cellField.getWidth() + 184);
}
if (type == 0) {
// 内容(第1-N行)
Integer rowNumber = 1;
for (int i = 0, length = rowList.size(); i < length; i++) {
T t = rowList.get(i);
Row row = sheet.createRow(rowNumber);
for (int j = 0; j < cellNumber; j++) {
Field field = getDeclaredField(t, cellFieldList.get(j).getCode());
field.setAccessible(true);
createCell(workbook, row, j, field.get(t), CellType.STRING, normalFont);
}
rowNumber++;
}
} else if (type == 1) {
// 内容(第1-N行)
Integer rowNumber = 1;
Row row = sheet.createRow(rowNumber);
for (int i = 0; i < cellNumber; i++) {
CellField cellField = cellFieldList.get(i);
createCell(workbook, row, i, rowData.get(cellField.getCode()), CellType.STRING, normalFont);
}
}
} catch (Exception e) {
// e.printStackTrace();
throw new CustomException(e.getMessage(), e);
}
}
//上述方法在调用是使用如下的参考
@RequestMapping("/trms/exportRedisStatis")
public ResponseEntity<byte[]> exportRedisStatis() {
ResponseEntity<byte[]> output = null;
ByteArrayOutputStream byteOutputStream = null;
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
List<RedisStatis> redisStatis = dbSyncBuilder.redisStatis();
byteOutputStream = new ByteArrayOutputStream();
List<CellField> cellFieldList = new ArrayList<>();
cellFieldList.add(new CellField("表名", "table"));
cellFieldList.add(new CellField("名称", "desc"));
cellFieldList.add(new CellField("总条数", "cnt"));
cellFieldList.add(new CellField("占用内存(单位:字节)", "memory"));
ExcelUtils.writeExcel(workbook, "shut名称", cellFieldList, redisStatis, null, 0);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment",
new String("shut-key数据统计".getBytes("GBK"), StandardCharsets.ISO_8859_1) + ".xlsx");
workbook.write(byteOutputStream);
output = new ResponseEntity<>(byteOutputStream.toByteArray(), headers, HttpStatus.OK);
} catch (Exception ex) {
log.error("导出shut统计结果异常", ex);
throw new CustomException("导出shut统计结果异常");
} finally {
try {
if (byteOutputStream != null) {
byteOutputStream.close();
}
} catch (IOException e) {
log.error("关闭输出流失败", e);
}
}
return output;
}
以上的是Excel操作之工具类 若需完整代码 可识别二维码后 给您发代码。