java实现excel的导入导出

最近查看了很多关于Excel中的中导入导出的文章和文档,发现一个严重的问题,就是距离最最近一次更新是17年。还是写的不完全的那种,有很多都是过期的函数没有去掉,本人在尝试了JXL和POI两种方法后,终于将这两种不同方法的工具测试出来了,下面直接上代码:

首先是JXL版本,一下有meven依赖包!

中央仓库地址

<!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl -->
<dependency>
    <groupId>net.sourceforge.jexcelapi</groupId>
    <artifactId>jxl</artifactId>
    <version>2.6.12</version>
</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>
包com.shjd.jinding.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import com.shjd.jinding.entity.TestO;
import jxl.Cell;
importjxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

class Excel {
	 / ** 
     *针对测试类进行导出的操作 
     * @参数列表 
     * /  
    public static void excleOut(List <TestO> list){  
        WritableWorkbook test = null;  
       try{  
            //创建一个excle对象  
            test = Workbook.createWorkbook(new File(“F:\\ test1.xls”));  
            //通过excle对象创建一个选项卡对象  
            WritableSheet sheet = test.createSheet(“sheet1”,0);  
            //创建一个单元格对象列行值  
            // Label label = new Label(0,2,“test”);  
            for(int i = 0; i <list.size(); i ++){  
                TestO test2 = list.get(i);  
                label1 = new Label(0,i,String.valueOf(test2.getId()));  
                label2 = new Label(1,i,test2.getName());  
                label3 = new Label(2,i,String.valueOf(test2.getAge()));  
  
                //将创建好的单元格对象放入选项卡中  
                sheet.addCell(label1的);  
                sheet.addCell(LABEL2);  
                sheet.addCell(LABEL3);  
            }  
            //写入目标路径  
            test.write();  
        catch(Exception e){  
            e.printStackTrace();  
        } finally {  
           try{  
                test.close();  
            } catch(WriteException | IOException e){  
                e.printStackTrace();  
            }  
        }  
    }  
    
    / ** 
     *针对TestO类进行的操作 
     * @返回 
     * /  
    public static List <TestO> excleIn(){  
        List <TestO> list = new ArrayList <TestO>();  
        工作簿worktest = null;  
        try{  
            //获取Ecle对象  
            worktest = Workbook.getWorkbook(new File(“F:\\ test.xls”));  
            //获取选项卡对象第0个选项卡  
            Sheet sheet = worktest.getSheet(0);  
            //循环选项卡中的值  
            for(int i = 0; i <sheet.getRows(); i ++){  
            	TestO test = new TestO();  
                //获取单元格对象  
                Cell cell0 = sheet.getCell(0,i);  
                如果(ⅰ> = 2)
                {
                	//取得单元格的值,并设置到对象中  
                	test.setId(Integer.valueOf(cell0.getContents()));  
                	//获取单元格对象,然后取得单元格的值,并设置到对象中  
                	test.setName(sheet.getCell(1,i).getContents());  
                	test.setAge(Integer.valueOf(sheet.getCell(2,i).getContents()));  
                	list.add(测试);                  	
                }
            }  
        catch(Exception e){  
            e.printStackTrace();  
        } finally {  
            worktest.close();  
        }  
        return list;  
    }  
    //将TESTO对象转换为TestVo用于导出。  
    private static List <TestVo> convertStu2VO(List <TestO> list){  
        List <TestVo> list2 = new ArrayList <TestVo>();  
        SimpleDateFormat sdf = new SimpleDateFormat(“yyyy / M / d HH:mm:ss”);  
        for(int i = 0; i <list.size(); i ++){  
            TestVo stuVo = new TestVo();  
            TestO stu = list.get(i);  
            stuVo.setName(stu.getName()); 
            stuVo.setId(stu.getId());
            stuVo.setAge(stu.getAge());
            
            list2.add(stuVo);  
        }  
  
        return list2;  
    }  
  
    public static void main(String [] args){  
    	FileInputStream fis = null;  
        try{  
            fis = new FileInputStream(“F:\\\\ test.xls”);  
            ExcelUtil <TestVo> util = new ExcelUtil <TestVo>((  
            		TestVo.class); //创建excel工具类  
            List <TestVo> list = util.importExcel(“”,fis); //导入  
            System.out.println(list);  
        } catch(FileNotFoundException e){  
            e.printStackTrace();  
        } 
    	 //初始数据  
      / * List <TestO> list = new ArrayList <TestO>();  
  
        TestO stu = new TestO();  
        stu.setId(1);  
        stu.setName( “李坤”);  
        stu.setAge(14);  
        list.add(STU);  
  
        TestO stu2 = new TestO();  
        stu2.setId(2);  
        stu2.setName( “曹贵生”);  
        stu2.setAge(20);  
        list.add(STU2);  
  
        TestO stu3 = new TestO();  
        stu3.setId(3);  
        stu3.setName( “李学宇”);  
        stu3.setAge(15);  
        list.add(stu3);  
  
        FileOutputStream out = null;  
        try{  
            out = new FileOutputStream(“F:\\\\ test.xls”);  
        } catch(FileNotFoundException e){  
            e.printStackTrace();  
        }  
        ExcelUtil <TestVo> util = new ExcelUtil <TestVo>(TestVo.class);  
        util.exportExcel(convertStu2VO(list),“学生信息”,60000,out);  
        System.out.println( “----执行完毕----------”); * /
        
        //sexcel.importFromExcel("F:\\\\test.xls","0“,(Class <TestO>)TestO.class,map);
        / * TestO test2 = new TestO();  
        test2.setId(1);  
        test2.setName( “书本名1”);  
        test2.setAge(13);  
        TestO test3 = new TestO();  
        test3.setId(2);  
        test3.setName( “书本名2”);  
        test3.setAge(42);  
        list.add(TEST2);  
        list.add(TEST3);  
        test.excleOut(列表); * /  
        / * for(TestO bo:Excel.excleIn()){  
            System.out.println(bo.getId()+“”+ bo.getName()+“”+ bo.getAge());  
        } * /
    }  
}

里面有对应的注解,基本上能满足基本的导入导出,当然,对于数据较多且对样式有要求的肯定是不能满足了,这个时候还有一个比较完善的poi版。

包com.shjd.jinding.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
impoort org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddressList;  
  
/ * 
 * ExcelUtil工具类实现功能: 
 *导出时传入列表<T>,即可实现导出为一个excel,其中每个对象T为Excel中的一条记录。 
 *导入时读取excel,得到的结果是一个list <T> .T是自己定义的对象。 
 *需要导出的实体对象只需简单配置注解就能实现灵活导出,通过注解您可以方便实现下面功能: 
 * 1.实体属性配置了注解就能导出到excel中,每个属性都对应一列。 
 * 2.列名称可以通过注解配置。 
 * 3.导出到哪一列可以通过注解配置。 
 * 4.鼠标移动到该列时提示信息可以通过注解配置。 
 * 5.用注解设置只能下拉选择不能随意填写功能。 
 * 6.用注解设置是否只导出标题而不导出内容,这在导出内容作为模板以供用户填写时比较实用。 
 *本工具类以后可能还会加功能,请关注我的博客:http://blog.csdn.net/lk_blog 
 * /  
public class ExcelUtil <T> {  
    Class <T> clazz;  
  
    public ExcelUtil(Class <T> clazz){  
        this.clazz = clazz;  
    }  
  
    
    public List <T> importExcel(String sheetName,InputStream input){  
        List <T> list = new ArrayList <T>();  
        try{  
            HSSFWorkbook workbook=new HSSFWorkbook(输入);  
            HSSFSheet sheet = workbook.getSheet(sheetName);  
            if(!sheetName.trim()。equals(“”)){  
                sheet = workbook.getSheet(sheetName); //如果指定sheet名,则取指定sheet的内容。  
            }  
            if(sheet == null){  
                sheet = workbook.getSheetAt(0); //如果传入的表名不存在则默认指向第1个表。  
            }  
            int rows = sheet.getPhysicalNumberOfRows();  
  
            if(rows> 0){//有数据时才处理  
                Field [] allFields = clazz.getDeclaredFields(); //得到类的所有字段。  
                Map <Integer,Field> fieldsMap = new HashMap <Integer,Field>(); //定义一个map用于存放列的序号和字段。  
                for(Field field:allFields){  
                    //将有注解的字段存放到地图中。  
                    if(field.isAnnotationPresent(ExcelVOAttribute.class)){  
                        ExcelVOAttribute attr =字段  
                                .getAnnotation(ExcelVOAttribute.class);  
                        int col = getExcelCol(attr.column()); //获得列号  
                        // System.out.println(col +“====”+ field.getName());  
                        field.setAccessible(true); //设置类的私有字段属性可访问。  
                        fieldsMap.put(col,field);  
                    }  
                }  
                for(int i = 1; i <rows; i ++){//从第2行开始取数据,默认第一行是表头。  
                    HSSFRow row = sheet.getRow(i);  
                    int cellNum = row.getPhysicalNumberOfCells();  
                    T entity = null;  
                    for(int j = 0; j <cellNum; j ++){  
                        HSSFCell cell = row.getCell(j);  
                        if(cell == null){  
                            return;  
                        }  
                        String c = cell.getStringCellValue();  
                        的System.out.println(C);  
                        if(c.equals(“”)){  
                            return;  
                        }  
                        entity =(entity == null?clazz.newInstance():entity); //如果不存在实例则新建。  
                        // System.out.println(cells [j] .getContents());  
                        Field field = fieldsMap.get(j); //从地图中得到对应列的字段。  
                        //取得类型,并根据对象类型设置值。  
                        Class <?> fieldType = field.getType();  
                        if(String.class == fieldType){  
                            field.set(entity,String.valueOf(c));  
                        } else if((Integer.TYPE == fieldType)  
                                || (Integer.class == fieldType)){  
                            field.set(entity,Integer.parseInt(c));  
                        } else if((Long.TYPE == fieldType)  
                                || (Long.class == fieldType)){  
                            field.set(entity,Long.valueOf(c));  
                        } else if((Float.TYPE == fieldType)  
                                || (Float.class == fieldType)){  
                            field.set(entity,Float.valueOf(c));  
                        } else if((Short.TYPE == fieldType)  
                                || (Short.class == fieldType)){  
                            field.set(entity,Short.valueOf(c));  
                        } else if((Double.TYPE == fieldType)  
                                || (Double.class == fieldType)){  
                            field.set(entity,Double.valueOf(c));  
                        } else if(Character.TYPE == fieldType){  
                            if((c!= null)&&(c.length()> 0)){  
                                field.set(entity,Character  
                                        .valueOf(c.charAt(0)));  
                            }  
                        }  
  
                    }  
                    if(entity!= null){  
                        list.add(entity);  
                    }  
                }  
                
            }  
  
        } catch(IOException e){  
            e.printStackTrace();  
        } catch(InstantiationException e){  
            e.printStackTrace();  
        } catch(IllegalAccessException e){  
            e.printStackTrace();  
        } catch(IllegalArgumentException e){  
            e.printStackTrace();  
        }  
        退货清单;  
    }  
  
    / ** 
     *对列表数据源将其里面的数据导入到excel表单 
     *  
     * @参数sheetName 
     *工作表的名称 
     * @参数sheetSize 
     *每个表中数据的行数,此数值必须小于65536 
     * @param输出 
     * java输出流 
     * /  
    public boolean exportExcel(List <T> list,String sheetName,int sheetSize,  
            OutputStream output){  
  
        Field [] allFields = clazz.getDeclaredFields(); //得到所有定义字段  
        List <Field> fields = new ArrayList <Field>();  
        //得到所有field并存放到一个list中。  
        for(Field field:allFields){  
            if(field.isAnnotationPresent(ExcelVOAttribute.class)){  
                fields.add(field);  
            }  
        }  
  
        HSSFWorkbook workbook = new HSSFWorkbook(); //产生工作薄对象  
  
        // excel2003中每个sheet中最多有65536行,为避免产生错误所以加这个逻辑。  
        if(sheetSize> 65536 || sheetSize <1){  
            sheetSize = 65536;  
        }  
        double sheetNo = Math.ceil(list.size()/ sheetSize); //取出一共有多少个工作表。  
        for(int index = 0; index <= sheetNo; index ++){  
            HSSFSheet sheet = workbook.createSheet(); //产生工作表对象  
            if(sheetNo == 0){  
                workbook.setSheetName(index,sheetName);  
            } else {  
                workbook.setSheetName(index,sheetName + index); //设置工作表的名称。  
            }  
            HSSFRow row;  
            HSSFCell cell; //产生单元格  
  
            row = sheet.createRow(0); //产生一行  
            //写入各个字段的列头名称  
            for(int i = 0; i <fields.size(); i ++){  
                Field field = fields.get(i);  
                ExcelVOAttribute attr =字段  
                        .getAnnotation(ExcelVOAttribute.class);  
                int col = getExcelCol(attr.column()); //获得列号  
                cell = row.createCell(col); //创建列                   
                cell.setCellValue(attr.name()); //写入列名  
  
                //如果设置了提示信息则鼠标放上去提示。  
                if(!attr.prompt().trim().equals(“”)){  
                    setHSSFPrompt(sheet,“”,attr.prompt(),1,100,col,col); //这里默认设了2-101列提示。  
                }  
                //如果设置了combo属性则本列只能选择不能输入  
                if(attr.combo().length> 0){  
                    setHSSFValidation(sheet,attr.combo(),1,100,col,col); //这里默认设了2-101列表只能选择不能输入。  
                }  
            }  
  
            int startNo = index * sheetSize;  
            int endNo = Math.min(startNo + sheetSize,list.size());  
            //写入各条记录,每条记录对应excel表中的一行  
            for(int i = startNo; i <endNo; i ++){  
                row = sheet.createRow(i + 1  -  startNo);  
                T vo =(T)list.get(i); //得到导出对象。  
                for(int j = 0; j <fields.size(); j ++){  
                    Field field = fields.get(j); //获得field。  
                    field.setAccessible(true); //设置实体类私有属性可访问  
                    ExcelVOAttribute attr =field  
                            .getAnnotation(ExcelVOAttribute.class);  
                    try{  
                        //根据ExcelVOAttribute中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列。  
                        if(attr.isExport()){  
                            cell = row.createCell(getExcelCol(attr.column())); //创建单元格                             
                            cell.setCellValue(field.get(vo)== null?“”  
                                    :String.valueOf(field.get(vo))); //如果数据存在就填入,不存在填入空格。  
                        }  
                    } catch(IllegalArgumentException e){  
                        e.printStackTrace();  
                    } catch(IllegalAccessException e){  
                        e.printStackTrace();  
                    }  
                }  
            }  
  
        }  
        try{  
            output.flush();  
            workbook.write(output);  
            output.close();  
            return true;  
        } catch(IOException e){  
            e.printStackTrace();  
            System.out.println(“输出已关闭”);  
            return false;  
        }  
  
    }  
  
    / ** 
     *将EXCEL中的A,B,C,D,E列映射成0,1,2,3 
     *  
     * @param col 
     * /  
    public static int getExcelCol(String col){  
        col = col.toUpperCase();  
        //从-1开始计算,字母重1开始运算。这种总数下来算数正好相同。  
        int count = -1;  
        char [] cs = col.toCharArray();  
        for(int i = 0; i <cs.length; i ++){  
            count + =(cs [i]  -  64)* Math.pow(26,cs.length  -  1  -  i);  
        }  
        返回计数;  
    }  
  
    / ** 
     *设置单元格上提示 
     *  
     * @参数表 
     *要设置的工作表。 
     * @参数promptTitle 
     *标题 
     * @param promptContent 
     *内容 
     * @参数firstRow 
     *开始行 
     * @param endRow 
     *结束行 
     * @param firstCol 
     *开始列 
     * @param endCol 
     *结束列 
     * @return设置好的工作表。 
     * /  
    public static HSSFSheet setHSSFPrompt(HSSFSheet表单,字符串promptTitle,  
            字符串promptContent,int firstRow,int endRow,int firstCol,  
            int endCol){  
        //构造约束对象  
        DVConstraint约束= DVConstraint  
                .createCustomFormulaConstraint( “DD1”);  
        //四个参数分别是:起始行,终止行,起始列,终止列  
        CellRangeAddressList regions = new CellRangeAddressList(firstRow,  
                endRow,firstCol,endCol);  
        //数据有效性对象  
        HSSFDataValidation data_validation_view = new HSSFDataValidation(  
                regions,constraint);  
        data_validation_view.createPromptBox(promptTitle,promptContent);  
        sheet.addValidationData(data_validation_view);  
        return sheet;  
    }  
  
    / ** 
     *设置某些列的值只能输入预制的数据,显示下拉框。 
     *  
     * @参数表 
     *要设置的工作表。 
     * @参数文本列表 
     *下拉框显示的内容 
     * @参数firstRow 
     *开始行 
     * @param endRow 
     *结束行 
     * @param firstCol 
     *开始列 
     * @param endCol 
     *结束列 
     * @return设置好的工作表。 
     * /  
    public static HSSFSheet setHSSFValidation(HSSFSheet表,  
            String [] textlist,int firstRow,int endRow,int firstCol,  
            int endCol){  
        //加载下拉列表内容  
        DVConstraint constraint= DVConstraint  
                .createExplicitListConstraint(textlist);  
        //设置数据有效性加载在哪个单元格上,四个参数分别是:起始行,终止行,起始列,终止列  
        CellRangeAddressList regions = new CellRangeAddressList(firstRow,  
                endRow,firstCol,endCol);  
        //数据有效性对象  
        HSSFDataValidation data_validation_list = new HSSFDataValidation(  
                地区,约束);  
        sheet.addValidationData(data_validation_list);  
        return sheet;  
    }  
}
测试类在第一个jxl下有这个静态方法,其中包括了poi的测试方法,朋友们在参考代码的时候这个不能直接用在开发工具上,有些地方中英文字符需要手动调下。如有不对之处还请指出谢谢。


猜你喜欢

转载自blog.csdn.net/weixin_41928646/article/details/80270477