POI入门(以及两个实用工具类)

简介: 1、HelloPOI 在我们实际的开发中,常常有需要导入导出excel和word的要求,POI便是一个很好的解决方案。 Apache的Jakata项目的POI子项目,目前比较成熟的是HSSF接口,处理MSExcel对象。它不象我们仅仅是用csv生成的没有格式的可以由Excel转换的东西,而是真正的Excel对象,你可以控制一些属性如sheet,cell等等

1、HelloPOI
在我们实际的开发中,常常有需要导入导出excel和word的要求,POI便是一个很好的解决方案。
Apache的Jakata项目的POI子项目,目前比较成熟的是HSSF接口,处理MSExcel对象。它不象我们仅仅是用csv生成的没有格式的可以由Excel转换的东西,而是真正的Excel对象,你可以控制一些属性如sheet,cell等等。
首先,理解一下一个Excel的文件的组织形式,一个Excel文件对应于一个workbook(HSSFWorkbook),一个workbook可以有多个sheet(HSSFSheet)组成,一个sheet是由多个row(HSSFRow)组成,一个row是由多个cell(HSSFCell)组成。
HSSF是指Excel2007年以前的版本,XSSF是指Excel2007年版本以后的版本。
2、例子
POIExcelUtil.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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;

public class POIExcelUtil {

    private int totalRows = 0;                      // 总行数
    private int totalCells = 0;                     // 总列数
    private OutputStream out = null;
    private HSSFWorkbook workbook = null;
    private HSSFSheet sheet = null;
    private HSSFRow row = null;                     // 定制浮点数格式
    private static String NUMBER_FORMAT = "#,##0.00";// 定制日期格式
    private static String DATE_FORMAT = "m/d/yy";   // "m/d/yy h:mm"

    public POIExcelUtil() {
    }

    // 根据文件名读取excel文件
    public List<ArrayList<String>> read(String fileName, int sheetNo,
            int beginRowNo, int endRowNo) {
        List<ArrayList<String>> dataLst = new ArrayList<ArrayList<String>>();
        // 检查文件名是否为空或者是否是Excel格式的文件
        if (fileName == null || !fileName.matches("^.+\\.(?i)((xls)|(xlsx))$")) {
            return dataLst;
        }
        boolean isExcel2003 = true;         // 对文件的合法性进行验
        if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
            isExcel2003 = false;
        }               // 检查文件是否存在
        File file = new File(fileName);
        if (file == null || !file.exists()) {
            return dataLst;
        }
        try {           // 读取excel
            dataLst = read(new FileInputStream(file), isExcel2003, sheetNo,
                    beginRowNo, endRowNo);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return dataLst;
    }
    // 根据流读取Excel文件
    public List<ArrayList<String>> read(InputStream inputStream,
            boolean isExcel2003, int sheetNo, int beginRowNo, int endRowNo) {
        List<ArrayList<String>> dataLst = null;
        try {
            // 根据版本选择创建Workbook的方式
            Workbook wb = isExcel2003 ? new HSSFWorkbook(inputStream)
                    : new HSSFWorkbook(inputStream);
            dataLst = read(wb, sheetNo, beginRowNo, endRowNo);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataLst;
    }
    // 得到总行数
    public int getTotalRows() {
        return totalRows;
    }
    // 得到总列数
    public int getTotalCells() {
        return totalCells;
    }
    // 读取数据
    private List<ArrayList<String>> read(Workbook wb, int sheetNo,
            int beginRowNo, int endRowNo) {
        List<ArrayList<String>> dataLst = new ArrayList<ArrayList<String>>();

        Sheet sheet = wb.getSheetAt(sheetNo - 1);// 得到第一个shell
        this.totalRows = sheet.getPhysicalNumberOfRows();
        if (this.totalRows >= 1 && sheet.getRow(0) != null) {
            this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
        }
        // 循环Excel的行
        // for (int r = 0; r < this.totalRows; r++) {
        for (int r = beginRowNo - 1; r < endRowNo; r++) {
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
            ArrayList<String> rowLst = new ArrayList<String>();
            // 循环Excel的列
            for (short c = 0; c < this.getTotalCells(); c++) {
                Cell cell = row.getCell(c);
                String cellValue = "";
                if (cell == null) {
                    rowLst.add(cellValue);
                    continue;
                }
                // 处理数字型的,自动去零
                if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
                    // 在excel里,日期也是数字,在此要进行判断
                    if (HSSFDateUtil.isCellDateFormatted(cell)) {
                        cellValue = DateUtil
                                .get4yMdHms(cell.getDateCellValue());
                    } else {
                        cellValue = getRightStr(cell.getNumericCellValue() + "");
                    }
                } else if (Cell.CELL_TYPE_STRING == cell.getCellType()) {   // 处理字符串型
                    cellValue = cell.getStringCellValue();
                } else if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) {  // 处理布尔型
                    cellValue = cell.getBooleanCellValue() + "";
                } else {    // 其它数据类型
                    cellValue = cell.toString() + "";
                }
                rowLst.add(cellValue);
            }
            dataLst.add(rowLst);
        }
        return dataLst;
    }
    // 正确地处理整数后自动加零的情况
    private String getRightStr(String sNum) {
        DecimalFormat decimalFormat = new DecimalFormat("#.000000");
        String resultStr = decimalFormat.format(new Double(sNum));
        if (resultStr.matches("^[-+]?\\d+\\.[0]+$")) {
            resultStr = resultStr.substring(0, resultStr.indexOf("."));
        }
        return resultStr;
    }
    /**
     * 初始化write
     */
    public void initWrite(OutputStream out) {
        this.out = out;
        this.workbook = new HSSFWorkbook();
        this.sheet = workbook.createSheet();
    }
    /**
     * 导出Excel文件
     * @throws Exception
     */
    public void export() throws Exception {
        try {
            workbook.write(out);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            throw new Exception("生成导出Excel文件出错! ", e);
        } catch (IOException e) {
            throw new Exception("写入Excel文件出错! ", e);
        }
    }

    /**
     * 增加一行
     * @param index   行号
     */
    public void createRow(int index) {
        this.row = this.sheet.createRow(index);
    }

    /**
     * 设置单元格
     * @param index    列号
     * @param value    单元格填充值
     */
    public void setCell(int index, int value) {
        HSSFCell cell = this.row.createCell(index);
        cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
        cell.setCellValue(value);
    }

    /**
     * 设置单元格
     * @param index 列号
     * @param value 单元格填充值
     */
    public void setCell(int index, double value) {
        HSSFCell cell = this.row.createCell(index);
        cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
        cell.setCellValue(value);
        HSSFCellStyle cellStyle = workbook.createCellStyle();       // 建立新的cell样式
        HSSFDataFormat format = workbook.createDataFormat();
        cellStyle.setDataFormat(format.getFormat(NUMBER_FORMAT));   // 设置cell样式为定制的浮点数格式
        cell.setCellStyle(cellStyle);                               // 设置该cell浮点数的显示格式
    }

    /**
     * 设置单元格
     * @param index  列号
     * @param value   单元格填充值
     */
    public void setCell(int index, String value) {
        HSSFCell cell = this.row.createCell(index);
        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
        cell.setCellValue(value);
    }

    /**
     * 设置单元格
     * @param index       列号
     * @param value       单元格填充值
     */
    public void setCell(int index, Calendar value) {
        HSSFCell cell = this.row.createCell(index);
        cell.setCellValue(value.getTime());
        HSSFCellStyle cellStyle = workbook.createCellStyle();   // 建立新的cell样式
        cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat(DATE_FORMAT)); // 设置cell样式为定制的日期格式
        cell.setCellStyle(cellStyle); // 设置该cell日期的显示格式
    }

    public static void main(String[] args) throws Exception {
        POIExcelUtil e = new POIExcelUtil();

        System.out.println(" 开始导出Excel文件 ");
        File f = new File("d://哈喽.xlsx");
        try {
            e.initWrite(new FileOutputStream(f));
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        e.createRow(0);
        e.setCell(0, "试题编码 ");
        e.setCell(1, "题型");
        e.setCell(2, "分值");
        e.setCell(3, "难度");
        e.setCell(4, "级别");
        e.setCell(5, "知识点");

        for(int i=1;i<10;i++)
        {
            e.createRow(i);
            e.setCell(0, "t"+i);
            e.setCell(1, 1+i);
            e.setCell(2, 3.0+i);
            e.setCell(3, 1+i);
            e.setCell(4, "重要"+i);
            e.setCell(5, "专业"+i);
        }
        try {
            e.export();
            System.out.println(" 导出Excel文件[成功] ");
        } catch (Exception ex) {
            System.out.println(" 导出Excel文件[失败] ");
            ex.printStackTrace();
        }
    }
}

DateUtil.java

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    // 得到当前的时间
    public static Date getDate() {
        Calendar canlendar = Calendar.getInstance();
        return canlendar.getTime();
    }
    // 提到指定的millis得到时间
    public static Date getDate(long millis) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.clear();
        canlendar.setTimeInMillis(millis);
        return canlendar.getTime();
    }

    public static long getMillis() {
        return Calendar.getInstance().getTimeInMillis();
    }
    // 得到指定日期的字符串(yyyy-MM-dd HH:mm:ss.SSS)
    public static String getDateFormate(Date date, String formate) {
        try {
            SimpleDateFormat simpleDateFormate = new SimpleDateFormat(formate);
            return simpleDateFormate.format(date);
        } catch (Exception e) {
        }
        return "";
    }
    // 根据日期得到YYYY-MM-DD HH:MM:SS.SSS格式字符串
    public static String get4yMdHmsS(Date date) {
        return DateUtil.getDateFormate(date, "yyyy-MM-dd HH:mm:ss.SSS");
    }
    // 根据日期得到YYYY-MM-DD HH:MM:SS格式字符串
    public static String get4yMdHms(Date date) {
        return DateUtil.getDateFormate(date, "yyyy-MM-dd HH:mm:ss");
    }
    // 根据日期得到YYYY-MM-DD HH:MM格式字符串
    public static String get4yMdHm(Date date) {
        return DateUtil.getDateFormate(date, "yyyy-MM-dd HH:mm");
    }
    // 根据日期得到YYYY-MM-DD格式字符串
    public static String get4yMd(Date date) {
        return DateUtil.getDateFormate(date, "yyyy-MM-dd");
    }
    // 把指定字符(yyyy-MM-dd HH:mm:ss.SSS)串转成Date
    public static Date parse4yMdHmsS(String sDate) {
        return DateUtil.parseDate(sDate, "yyyy-MM-dd HH:mm:ss.SSS");
    }
    // 把指定字符(yyyy-MM-dd HH:mm:ss)串转成Date
    public static Date parse4yMdHms(String sDate) {
        return DateUtil.parseDate(sDate, "yyyy-MM-dd HH:mm:ss");
    }
    // 把指定字符(yyyy-MM-dd HH:mm)串转成Date
    public static Date parse4yMdHm(String sDate) {
        return DateUtil.parseDate(sDate, "yyyy-MM-dd HH:mm");
    }
    // 把指定字符(yyyy-MM-dd)串转成Date
    public static Date parse4yMd(String sDate) {
        return DateUtil.parseDate(sDate, "yyyy-MM-dd");
    }
    // 根据指定格式,把字符串转成日期
    public static Date parseDate(String sDate, String formate) {
        SimpleDateFormat simpleDateFormate = new SimpleDateFormat(formate);
        try {
            return simpleDateFormate.parse(sDate);
        } catch (ParseException e) {
            return null;
        }
    }

    // 两个长整型的时间相差(时间的毫秒数),可以得到指定的毫秒数,秒数,分钟数,天数
    public static double getDifTwoTime(Date minuendTime, Date subtrahendTime,
            String tdatestr) {
        if (minuendTime == null || subtrahendTime != null) {
            return DateUtil.getDifTwoTime(minuendTime.getTime(),
                    subtrahendTime.getTime(), tdatestr);
        }
        return 0;
    }

    // 两个长整型的时间相差(时间的毫秒数),可以得到指定的毫秒数,秒数,分钟数,天数
    public static double getDifTwoTime(long minuendTime, long subtrahendTime,
            String tdatestr) {
        if (tdatestr == null || tdatestr.equals("")) {
            tdatestr = "MS";
        }
        double temp = 1;
        /** 毫秒数 */
        if ("MS".equalsIgnoreCase(tdatestr)) {
            temp = 1;
        }
        /** 得到秒 */
        if ("S".equalsIgnoreCase(tdatestr)) {
            temp = 1000;
        }
        /** 得到分 */
        if ("M".equalsIgnoreCase(tdatestr)) {
            temp = 1000 * 60;
        }
        /** 得到小时 */
        if ("H".equalsIgnoreCase(tdatestr)) {
            temp = 1000 * 60 * 60;
        }
        /** 得到天 */
        if ("D".equalsIgnoreCase(tdatestr)) {
            temp = 1000 * 60 * 60 * 24;
        }
        return (minuendTime - subtrahendTime) / temp;
    }

    // 从日期中得到指定部分(YYYY/MM/DD/HH/SS/SSS)数字
    public static int getPartOfTime(Date date, String part) {
        Calendar canlendar = Calendar.getInstance();
        canlendar.clear();
        canlendar.setTime(date);
        if (part.equalsIgnoreCase("Y")) {// 得到年
            return canlendar.get(Calendar.YEAR);
        }
        if (part.equalsIgnoreCase("M")) {// 得到月
            return canlendar.get(Calendar.MONTH) + 1;
        }
        if (part.equalsIgnoreCase("D")) {// 得到日
            return canlendar.get(Calendar.DAY_OF_MONTH);
        }
        if (part.equalsIgnoreCase("H")) {// 得到时
            return canlendar.get(Calendar.HOUR_OF_DAY);
        }
        if (part.equalsIgnoreCase("M")) {// 得到分
            return canlendar.get(Calendar.MINUTE);
        }
        if (part.equalsIgnoreCase("S")) {// 得到秒
            return canlendar.get(Calendar.SECOND);
        }
        if (part.equalsIgnoreCase("MS")) {// 得到毫秒
            return canlendar.get(Calendar.MILLISECOND);
        }
        return -1;
    }
}
目录
相关文章
|
7月前
|
easyexcel Java 测试技术
读取Excel还用POI?试试这款开源工具EasyExcel
读取Excel还用POI?试试这款开源工具EasyExcel
186 0
|
C#
45【软件技术基础】C#调用NPOI插件对EXCEL进行处理
NPOI插件进行EXCEL表格处理,不依赖第三方软件,功能强大,使用简便。 C#调用NPOI插件进行EXCEL单个表和文件夹中批量表的处理。
220 1
|
Java Apache
超实用!教你如何在POI-TL框架中熟练使用Configure类,快速完成Office文档生成!
POI-TL是一个用于生成Office文档的Java库,Configure类是该库中的一个配置类,其作用是提供了一些全局的配置选项,可以用于定制化生成的文档。
502 0
|
Java API Apache
POI简介,以及使用POI技术实现Excel文件的导入导出案例
POI简介,以及使用POI技术实现Excel文件的导入导出案例
361 0
POI简介,以及使用POI技术实现Excel文件的导入导出案例
Java使用itext非模板方式生成PDF表格文件2
Java使用itext非模板方式生成PDF表格文件2
Java使用itext运用非模板方式生成PDF文件1
Java使用itext运用非模板方式生成PDF文件1
|
Java
Java 技术篇-使用poi开源jar包实现读取excel实例演示,poi-3.17.jar获取
Java 技术篇-使用poi开源jar包实现读取excel实例演示,poi-3.17.jar获取
391 0
Java 技术篇-使用poi开源jar包实现读取excel实例演示,poi-3.17.jar获取
|
Java 程序员 API
Java:Java的jar包之POI的简介、安装、使用方法(基于POI将Word、Excel、PPT转换为html)之详细攻略
Java:Java的jar包之POI的简介、安装、使用方法(基于POI将Word、Excel、PPT转换为html)之详细攻略
|
Java Apache API
POI框架:Java程序读取Excel
APACHE-POI What:POI是什么? Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
2334 0
推荐一个有用的Excel操作类库 LinqToExcel
GitHub: LinqToExcel 以前项目中对Excel进行信息读取,我都是使用的NPOI的封装类,给定一个fileurl,然后返回给我一个datatable。
1262 0