在项目开发中,我们可能需要将数据导出成excel。如果excel的标题都是只占用一个单元格,那可以直接通过某些excel工具类直接生成就行了。但实际情况中表格标题并没有那么简单,可能一个标题有子标题,而子标题里又有子标题,这种情况下就无法使用工具类直接实现了,而手写又太麻烦。这篇文章做的即是直接读取现有的excel表,生成可以生成当前excel表的java代码,以后开发上只需要将生成的java代码贴进自己项目里,便可以直接使用了。
本次代码使用到了hutool和poi的依赖
org.apache.poi
poi-ooxml
4.1.2
cn.hutool
hutool-all
5.4.3
代码如下(实例):
String excelFilePath = "现有的excel表格地址";
FileInputStream fis = new FileInputStream(excelFilePath);
Workbook workbook = new HSSFWorkbook(fis);
int headerRowNum = workbook.getSheetAt(0).getLastRowNum();
fis.close();
ExcelReader excelReader = ExcelUtil.getReader(new File(excelFilePath));
List> read = excelReader.read(0, headerRowNum);
excelReader.close();
代码如下(示例):
// 获取标题结构
public static Map> getMap(List> read){
Map> map = new HashMap<>();
int i = 0;
for (List
由于用的是ArrayList,所以增删的操作有点麻烦,如果可以,你可以把ArrayList改成LinkedList。这里的list所存放的内容如注释所表示。 由于这里使用的是HashMap来存储,需要注意两个点:
排序这里我是按每个list的起始列来排序,这样就可以对应现有的excel表了
// 按起始列排序
public static List>> sortMap(Map> map) {
//利用Map的entrySet方法,转化为list进行排序
List>> entryList = new ArrayList<>(map.entrySet());
//利用Collections的sort方法对list排序
Collections.sort(entryList, (o1, o2) -> {
//正序排列,倒序反过来
return o1.getValue().get(2) - o2.getValue().get(2);
});
return entryList;
}
这里大多都是拼接字符串啦,只要细心点就行了。
// 生成java代码
public static void javaGenator(List>> stringList,int headerRowNum,Workbook workbook){
Sheet sheet = workbook.getSheetAt(0);
final String excelName = "MyExcelName";
File file = new File("D:\\"+ excelName +".java");
final String excelAddress = "C:\\\\test2.xls"; // 由于\\字符串会被识别为\,因此这里需要写四个\
try (FileWriter fw = new FileWriter(file); PrintWriter pw = new PrintWriter(fw)) {
pw.println("import cn.hutool.poi.excel.ExcelUtil;");
pw.println("import cn.hutool.poi.excel.ExcelWriter;");
pw.println("public class " + excelName +"{");
pw.print(" ");
pw.println("public static void main(String[] args){");
pw.print(" ");
pw.println("ExcelWriter writer = ExcelUtil.getWriter(\""+ excelAddress +"\");");
for (Map.Entry> listEntry : stringList) {
String name = listEntry.getKey();
List list = listEntry.getValue();
int minRow = list.get(0);
int maxRow = list.get(1);
int minCal = list.get(2);
int maxCal = list.get(3);
pw.print(" ");
pw.println("writer.setColumnWidth(" + minCal + ", "+ sheet.getColumnWidth(minCal)/100 +");");
pw.print(" ");
pw.println("writer.merge("+ minRow +", " + maxRow + ", " + minCal + ", " + maxCal +", \""+ name +"\", false);");
}
for (int j = 0; j <= headerRowNum; j++) {
pw.print(" ");
pw.println("writer.passCurrentRow();");
}
pw.print(" ");
pw.println("writer.flush();");
pw.print(" ");
pw.println("writer.close();");
pw.print(" ");
pw.println("}");
pw.println("}");
}catch (Exception e){
e.printStackTrace();
}
}
完整代码
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import java.io.*;
import java.util.*;
/**
* @author Namego
* @date 2023/4/16 21:44
*/
public class MyExcelUtil {
public static void main(String[] args) throws IOException {
String excelFilePath = "C:\\response2.xls";
FileInputStream fis = new FileInputStream(excelFilePath);
Workbook workbook = new HSSFWorkbook(fis);
int headerRowNum = workbook.getSheetAt(0).getLastRowNum();
fis.close();
ExcelReader excelReader = ExcelUtil.getReader(new File(excelFilePath));
List> read = excelReader.read(0, headerRowNum);
excelReader.close();
Map> map = getMap(read);
List>> stringList = sortMap(map);
javaGenator(stringList,headerRowNum,workbook);
workbook.close();
}
// 生成java代码
public static void javaGenator(List>> stringList,int headerRowNum,Workbook workbook){
Sheet sheet = workbook.getSheetAt(0);
final String excelName = "MyExcelName";
File file = new File("D:\\"+ excelName +".java");
final String excelAddress = "C:\\\\test2.xls"; // 由于\\字符串会被识别为\,因此这里需要写四个\
try (FileWriter fw = new FileWriter(file); PrintWriter pw = new PrintWriter(fw)) {
pw.println("import cn.hutool.poi.excel.ExcelUtil;");
pw.println("import cn.hutool.poi.excel.ExcelWriter;");
pw.println("public class " + excelName +"{");
pw.print(" ");
pw.println("public static void main(String[] args){");
pw.print(" ");
pw.println("ExcelWriter writer = ExcelUtil.getWriter(\""+ excelAddress +"\");");
for (Map.Entry> listEntry : stringList) {
String name = listEntry.getKey();
List list = listEntry.getValue();
int minRow = list.get(0);
int maxRow = list.get(1);
int minCal = list.get(2);
int maxCal = list.get(3);
pw.print(" ");
pw.println("writer.setColumnWidth(" + minCal + ", "+ sheet.getColumnWidth(minCal)/100 +");");
pw.print(" ");
pw.println("writer.merge("+ minRow +", " + maxRow + ", " + minCal + ", " + maxCal +", \""+ name +"\", false);");
}
for (int j = 0; j <= headerRowNum; j++) {
pw.print(" ");
pw.println("writer.passCurrentRow();");
}
pw.print(" ");
pw.println("writer.flush();");
pw.print(" ");
pw.println("writer.close();");
pw.print(" ");
pw.println("}");
pw.println("}");
}catch (Exception e){
e.printStackTrace();
}
}
// 获取标题结构
public static Map> getMap(List> read){
Map> map = new HashMap<>();
int i = 0;
for (List
由于是用main函数来测试的,所以方法都是静态,可以根据你实际情况修改