java读取excel表,生成可以生成当前excel表的java代码

前言

在项目开发中,我们可能需要将数据导出成excel。如果excel的标题都是只占用一个单元格,那可以直接通过某些excel工具类直接生成就行了。但实际情况中表格标题并没有那么简单,可能一个标题有子标题,而子标题里又有子标题,这种情况下就无法使用工具类直接实现了,而手写又太麻烦。这篇文章做的即是直接读取现有的excel表,生成可以生成当前excel表的java代码,以后开发上只需要将生成的java代码贴进自己项目里,便可以直接使用了。

一、引入依赖

本次代码使用到了hutool和poi的依赖


    org.apache.poi
    poi-ooxml
    4.1.2



    cn.hutool
    hutool-all
    5.4.3

二、读取Excel

代码如下(实例):

	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 objects : read) {
            int cal = 0;
            for (Object object : objects) {
                if(map.containsKey(object.toString())){
                    List list = map.get(object.toString());
                    Integer maxCal = list.get(3);
                    Integer minCal = list.get(2);
                    list.remove(3);
                    list.remove(2);
                    list.remove(1);
                    list.add(i);
                    list.add(minCal);
                    // 当前列数和该标题所存的列数谁更大,谁大用谁
                    list.add(Math.max(cal,maxCal));
                    map.put(object.toString(),list);
                }else{
                    ArrayList list = new ArrayList<>();
                    // 起始行
                    list.add(i);
                    // 末尾行
                    list.add(i);
                    // 起始列
                    list.add(cal);
                    // 末尾列
                    list.add(cal);
                    map.put(object.toString(),list);
                }
                cal++;
            }
            i++;
        }
        return map;
    }
 
  
由于用的是ArrayList,所以增删的操作有点麻烦,如果可以,你可以把ArrayList改成LinkedList。这里的list所存放的内容如注释所表示。 由于这里使用的是HashMap来存储,需要注意两个点:
  1. 最后遍历map的时候,其顺序并不会跟我们原先excel表里的标题顺序一样,因此需要进行排序。
  2. map的key不能重复,这也导致表里的标题命名不能重复,不然会重复合并单元格,代码会报错。当然我还没见过标题会重复的excel(hh)。所以应该没多大问题。如果真的有重复的标题,应该就需要采用别的数据结构了。

排序这里我是按每个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代码

这里大多都是拼接字符串啦,只要细心点就行了。

   // 生成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 objects : read) {
            int cal = 0;
            for (Object object : objects) {
                if(map.containsKey(object.toString())){
                    List list = map.get(object.toString());
                    Integer maxCal = list.get(3);
                    Integer minCal = list.get(2);
                    list.remove(3);
                    list.remove(2);
                    list.remove(1);
                    list.add(i);
                    list.add(minCal);
                    list.add(Math.max(cal,maxCal));
                    map.put(object.toString(),list);
                }else{
                    ArrayList list = new ArrayList<>();
                    // 起始行
                    list.add(i);
                    // 末尾行
                    list.add(i);
                    // 起始列
                    list.add(cal);
                    // 末尾列
                    list.add(cal);
                    map.put(object.toString(),list);
                }
                cal++;
            }
            i++;
        }
        return map;
    }

    // 按起始列排序
    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;
    }
}
 
  

由于是用main函数来测试的,所以方法都是静态,可以根据你实际情况修改

你可能感兴趣的:(IT技术系列,excel,java,开发语言)