精华内容
下载资源
问答
  • 2020-07-17 09:41:37

    使用读取excel工具类的例子,例子中,使用简单,对比灵活。代码简洁。

    说明:这块代码是网上别人公开的,具体来源找不到了。我把它做了修改,抽离固定的实体,改成泛型,这样更加灵活。如果侵权,请通知博主。


    一.编写工具类

    工具类代码:

    package com.system.util;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.List;
    
    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;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    import freemarker.log.Logger;
    
    /**
     * Author: laijieuan
     * Date: 2020-07-07
     * Description: 读取Excel内容 
     * T 泛型是接收每行数据的类名
     */
    public abstract class ExcelReader<T> {
    
        private static Logger logger = Logger.getLogger(ExcelReader.class.getName()); // 日志打印类
    
        private static final String XLS = "xls";
        private static final String XLSX = "xlsx";
    
        /**
         * 根据文件后缀名类型获取对应的工作簿对象
         * @param inputStream 读取文件的输入流
         * @param fileType 文件后缀名类型(xls或xlsx)
         * @return 包含文件数据的工作簿对象
         * @throws IOException
         */
        public Workbook getWorkbook(InputStream inputStream, String fileName) throws IOException {
            Workbook workbook = null;
            if (fileName.endsWith(XLS)) {
                workbook = new HSSFWorkbook(inputStream);
            } else if (fileName.endsWith(XLSX)) {
                workbook = new XSSFWorkbook(inputStream);
            }
            return workbook;
        }
    
        /**
         * 读取Excel文件内容
         * @param fileName 要读取的Excel文件所在路径
         * @return 读取结果列表,读取失败时返回null
         */
        public List<T> readExcel(String fileName) {
    
            Workbook workbook = null;
        
            FileInputStream inputStream = null;
    
            try {
                // 获取Excel后缀名
                String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
                // 获取Excel文件
                File excelFile = new File(fileName);
                if (!excelFile.exists()) {
                    logger.warn("指定的Excel文件不存在!");
                    return null;
                }
    
                // 获取Excel工作簿
                inputStream = new FileInputStream(excelFile);
                workbook = getWorkbook(inputStream, fileType);
    
                // 读取excel中的数据
                List<T> resultDataList = parseExcel(workbook);
    
                return resultDataList;
            } catch (Exception e) {
                logger.warn("解析Excel失败,文件名:" + fileName + " 错误信息:" + e.getMessage());
                return null;
            } finally {
                try {
                    
                    if (null != inputStream) {
                        inputStream.close();
                    }
                } catch (Exception e) {
                    logger.warn("关闭数据流出错!错误信息:" + e.getMessage());
                    return null;
                }
            }
        }
    
        /**
         * 解析Excel数据
         * @param workbook Excel工作簿对象 
         * @return 解析结果
         */
        public  List<T> parseExcel(Workbook workbook) {
           List<T> resultDataList = new ArrayList<>();
            // 解析sheet
            for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
                Sheet sheet = workbook.getSheetAt(sheetNum);
    
                // 校验sheet是否合法
                if (sheet == null) {
                    continue;
                }
    
                // 获取第一行数据
                int firstRowNum = sheet.getFirstRowNum();
                Row firstRow = sheet.getRow(firstRowNum);
                if (null == firstRow) {
                    logger.warn("解析Excel失败,在第一行没有读取到任何数据!");
                }
    
                // 解析每一行的数据,构造数据对象
                int rowStart = firstRowNum + 1;
                int rowEnd = sheet.getPhysicalNumberOfRows();
                for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
                    Row row = sheet.getRow(rowNum);
    
                    if (null == row) {
                        continue;
                    }
    				//读取当前行的数据,该方法需要重写
                    T resultData = convertRowToData(row);
                    if (null == resultData) {
                        logger.warn("第 " + row.getRowNum() + "行数据不合法,已忽略!");
                        continue;
                    }
                    resultDataList.add(resultData);
                }
            }
    
            return resultDataList;
        }
    
        /**
         * 将单元格内容转换为字符串
         * @param cell
         * @return
         */
        public static String convertCellValueToString(Cell cell) {
            if(cell==null){
                return null;
            }
            String returnValue = null;
            switch (cell.getCellType()) {
                case Cell.CELL_TYPE_NUMERIC:   //数字
                    Double doubleValue = cell.getNumericCellValue();
    
                    // 格式化科学计数法,取一位整数
                    DecimalFormat df = new DecimalFormat("0");
                    returnValue = df.format(doubleValue);
                    break;
                case Cell.CELL_TYPE_STRING:    //字符串
                    returnValue = cell.getStringCellValue();
                    break;
                case Cell.CELL_TYPE_BOOLEAN:   //布尔
                    Boolean booleanValue = cell.getBooleanCellValue();
                    returnValue = booleanValue.toString();
                    break;
                case Cell.CELL_TYPE_BLANK:     // 空值
                    break;
                case Cell.CELL_TYPE_FORMULA:   // 公式
                    returnValue = cell.getCellFormula();
                    break;
                case Cell.CELL_TYPE_ERROR:     // 故障
                    break;
                default:
                    break;
            }
            return returnValue;
        }
    
        /**
         * 为了灵活使用该工具类,抽取泛型来完成
         * 提取每一行中需要的数据,构造成为一个结果数据对象
         * 当该行中有单元格的数据为空或不合法时,忽略该行的数据
         *
         * @param row 行数据
         * @return 解析后的行数据对象,行数据错误时返回null
         */
        public abstract T convertRowToData(Row row);
    }
    
    

    工具类就此写完了


    二.例子说明

    现在有一个类的实体是这样的:

    package com.wl.differentCountries.entity;
    /**
      *国别类
      */
    public class Country {
        /**
         * 国别代码
         */
        private String countrycode;
    
        /**
         * 国别中文简称
         */
        private String countryname;
    
        /**
         * 国别英文简称
         */
        private String countryenname;
    
        /**
         * 国别英文缩写
         */
        private String countryenshort;
    
        /**
         * 优普税率
         */
        private String applytaxtype;
    
        /**
         * 国别描述
         */
        private String countrydesc;
    
        /**
         * 备注
         */
        private String comments;
    
        /**
         * 状态
         */
        private String states;
    
        /**
         * 最终目的国别代码
         */
        private String lastcountrycode;
    
        public String getCountrycode() {
            return countrycode;
        }
        public void setCountrycode(String countrycode) {
            this.countrycode = countrycode == null ? null : countrycode.trim();
        }
        public String getCountryname() {
            return countryname;
        }
        public void setCountryname(String countryname) {
            this.countryname = countryname == null ? null : countryname.trim();
        }
        public String getCountryenname() {
            return countryenname;
        }
        public void setCountryenname(String countryenname) {
            this.countryenname = countryenname == null ? null : countryenname.trim();
        }
        public String getCountryenshort() {
            return countryenshort;
        }
        public void setCountryenshort(String countryenshort) {
            this.countryenshort = countryenshort == null ? null : countryenshort.trim();
        }
        public String getApplytaxtype() {
            return applytaxtype;
        }
        public void setApplytaxtype(String applytaxtype) {
            this.applytaxtype = applytaxtype == null ? null : applytaxtype.trim();
        }
        public String getCountrydesc() {
            return countrydesc;
        }
        public void setCountrydesc(String countrydesc) {
            this.countrydesc = countrydesc == null ? null : countrydesc.trim();
        }
        public String getComments() {
            return comments;
        }
        public void setComments(String comments) {
            this.comments = comments == null ? null : comments.trim();
        }
        public String getStates() {
            return states;
        }  
        public void setStates(String states) {
            this.states = states == null ? null : states.trim();
        }
        public String getLastcountrycode() {
            return lastcountrycode;
        }
        public void setLastcountrycode(String lastcountrycode) {
            this.lastcountrycode = lastcountrycode == null ? null : lastcountrycode.trim();
        }
    	@Override
    	public String toString() {
    		return "Country [countrycode=" + countrycode + ", countryname=" + countryname + ", countryenname="
    				+ countryenname + ", countryenshort=" + countryenshort + ", applytaxtype=" + applytaxtype
    				+ ", countrydesc=" + countrydesc + ", comments=" + comments + ", states=" + states
    				+ ", lastcountrycode=" + lastcountrycode + "]";
    	}
        
    }
    

    然后这个实体的数据基本都是由公司的人员从excel里的填写好后,上传到系统,系统读取excel并封装成的

    excel模板:

    国别代码国别中文简称国别英文简称国别英文缩写优普税率国别描述备注状态最终目的国别代码
    502美国XXUAXXXXXXXXXYXXX

    第一步:继承excelReader工具类并重写读取数据方法。

    package com.wl.differentCountries.utils;
    
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    
    import com.system.util.ExcelReader;
    import com.wl.differentCountries.entity.Country;
    
    /**
     * 针对这个国别类封装一个工具
     * 必须继承ExcelReader<T>
     * T是自由的,当然,既然针对的是国别类,这里就是写国别类
     */
    public class CountryExcelReader extends ExcelReader<Country>{
    	/*重写方法,读取每一行数据并封装成实体*/
    	@Override
    	public Country convertRowToData(Row row) {
            //先new一个国别实体
    		Country resultData = new Country();
    		//
    		Cell cell;
            //当前列号,默认值0
    		int cellNum = 0;
    		//获取最大列号,
            row.getPhysicalNumberOfCells();
    		//通过行获取列 获取第一列
            cell = row.getCell(cellNum++);
            
    		// 获取国别代码 读取数据并装成String
    		String countryCode = convertCellValueToString(cell);
            //封装至实体属性
    		resultData.setCountrycode(countryCode);
            
    		//通过行获取列 获取第二列 以下就以此类推,有多少列就读多少次,也可以通过最大的列数号遍历,通过反射完成封装,这里就不弄这么复杂的了。
    		cell = row.getCell(cellNum++);
            // 获取国别中文简称 
    		String countryname = convertCellValueToString(cell);
    		resultData.setCountryname(countryname);
    		// 获取国别英文简称
    		cell = row.getCell(cellNum++);
    		String countryenname = convertCellValueToString(cell);
    		resultData.setCountryenname(countryenname);
    		// 获取国别英文缩写
    		cell = row.getCell(cellNum++);
    		String countryenshort = convertCellValueToString(cell);
    		resultData.setCountryenshort(countryenshort);
    		// 获取优普税率
    		cell = row.getCell(cellNum++);
    		String applytaxtype = convertCellValueToString(cell);
    		resultData.setApplytaxtype(applytaxtype);
    		// 获取国别描述
    		cell = row.getCell(cellNum++);
    		String countrydesc = convertCellValueToString(cell);
    		resultData.setCountrydesc(countrydesc);
    		// 获取备注
    		cell = row.getCell(cellNum++);
    		String comments = convertCellValueToString(cell);
    		resultData.setComments(comments);
    		// 获取状态
    		cell = row.getCell(cellNum++);
    		String states = convertCellValueToString(cell);
    		resultData.setComments(comments);
    		// 获取最终目的国别代码
    		cell = row.getCell(cellNum++);
    		String lastcountrycode = convertCellValueToString(cell);
    		resultData.setLastcountrycode(lastcountrycode);
    		return resultData;
    	}
    
    }
    
    

    Controller层:获取上传的excel文件

    package com.wl.differentCountries.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import com.system.util.ResultUtils;
    import com.system.vo.Result;
    import com.wl.differentCountries.entity.Country;
    import com.wl.differentCountries.service.WLCountryService;
    
    /**
     * 
     * @author laijieguan
     * 2020-07-10
     */
    @RestController
    @RequestMapping("country")
    public class CountryController {
    	@Autowired
    	private WLCountryService wlCountryService;
    	/**
    	 * 根据国别代码来查询
    	 */
    	@RequestMapping("selByCountryCode")
    	private Result<Object> selByCountryCode(String countryCode){
    		System.out.println(countryCode);
    		Country country = wlCountryService.selectByPrimaryKey(countryCode);
    		if(country != null) {
    			return ResultUtils.data(country);
    		}
    		return ResultUtils.error("未查询到相关国别信息!");
    	}
    	
        /**
         *获取上传的文件
         */
    	@RequestMapping("importCountryData")
    	private Result<Object> importCountryData(@RequestParam(value = "file", required = false) MultipartFile mFile) {
            //这个地方应该对该文件的格式做判断,如果不是excel的话返回提示
    		String type = "";
    		try {
    			Boolean importAddr = wlCountryService.importAddr(mFile, type);
    			if (importAddr) {
    				return ResultUtils.success("导入成功");
    			} else {
    				return ResultUtils.error("导入失败");
    			}
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			return ResultUtils.error("导入失败");
    		}
    	}
    }
    
    

    Service层:读取数据,并对数据进行业务处理

    package com.wl.differentCountries.service;
    
    import java.io.InputStream;
    import java.util.List;
    
    import org.apache.poi.ss.usermodel.Workbook;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.web.multipart.MultipartFile;
    
    import com.wl.differentCountries.dao.WLCountryMapper;
    import com.wl.differentCountries.entity.Country;
    import com.wl.differentCountries.utils.CountryExcelReader;
    
    @Service
    @Transactional
    public class WLCountryServiceImpl implements WLCountryService{
    	@Autowired
    	private WLCountryMapper wlCountryMapper;
    	
    	@Override
    	public Integer insert(Country country) {
    		return wlCountryMapper.insert(country);
    	}
    
    	@Override
    	public Country selectByPrimaryKey(String countryCode) {
    		return wlCountryMapper.selectByPrimaryKey(countryCode);
    	}
    
    	@Override
    	public Integer updateByPrimaryKeySelective(Country country) {
    		return wlCountryMapper.updateByPrimaryKeySelective(country);
    	}
    	
        /**
         *读取excel数据
         */
    	@Override
    	public Boolean importAddr(MultipartFile mFile, String type) throws Exception {
            //获取流
    		InputStream inputStream = mFile.getInputStream();
            //获取文件名
    		String fileName = mFile.getOriginalFilename();
            //new 一个读取对应实体的excel读解器
    		CountryExcelReader countryExcelReader = new CountryExcelReader();
    		//通过流来获取workbook实体
            Workbook wb = countryExcelReader.getWorkbook(inputStream, fileName);
    		//解析excel数据,封装后返回List集合
            List<Country> parseExcel = countryExcelReader.parseExcel(wb);
    		int count = 0;
            //遍历每一实例,做对应的业务操作。
    		for(int i = 0 ;i< parseExcel.size();i++) {
    			System.out.println(parseExcel.get(i));
    		}
    		if(count == parseExcel.size()) { //这个是我的业务操作需要的,业务代码已经删除各位根据自己情况完成即可
    			return true;
    		}
    		return false;
    	}
    	
    
    

    在读取每列数据的时候,其实是不太灵活的,可以做成代理模式。具体的我就不详细说了,因为这块代码实现属于机密。哈哈哈哈哈。

    更多相关内容
  • 前言 实习期间遇到一个业务需求,要求具有excel导入和导出功能。由于公司框架的数据表格自带了excel导出功能(N年前的老框架,文档不全BUG贼多),所以只需怼excel导入即可,流程是这样的:选择excel →文件...Java

    前言

    实习期间遇到一个业务需求,要求具有excel导入和导出功能。由于公司框架的数据表格自带了excel导出功能,所以只需excel导入即可,流程是这样的:选择excel →文件上传→处理数据。

    项目使用的Jar包是Apache POI,关于Apache POI,简单介绍一下:

    Apache POI是基于Office Open XML标准(OOXML)和Microsoft的OLE2复合文档格式(OLE2)处理各种文件格式的开源项目。简言之,就是用来操作office的工具箱。

    其中操作Excel的模块有两个:

    • HSSF - 操作xls格式excel(低版本),有数据量限制
    • XSSF - 操作xlsx格式excel(高版本),支持百万级数据量

    1、工作准备

    打开maven仓库:https://mvnrepository.com/,输入POI,如下图:
    在这里插入图片描述
    点进去,推荐选择的版本特点——时间不早不晚,多人使用的(遇到问题降低了解决难度),如下图:
    在这里插入图片描述
    这里选择3.17版本(beta可以理解为测试、抢先,通常是有新功能或大的调整),点击,复制maven坐标,如下图:
    在这里插入图片描述
    poi-ooxml如是,然后把它们贴入pom.xml,如下图:
    在这里插入图片描述
    然后在idea中右键选中:Maven→Reimport,或者点击enable auto import,让maven把jar包接入项目即可。

    2、小试牛刀

    由于excel存在版本区别,需要分别处理xls和xlsx格式,分别对应HSSF、XSSF开头的API,按住CTRL + SHIFT + ALT + U,查看继承关系图,可以发现它们有相同的接口:
    在这里插入图片描述在这里插入图片描述
    其它类,如:HSSFSheet、XSSFSheet也可以通过Sheet接口引用(里式替换法则),测试代码如下(xlxs):

        private static void parseXlsxDemo() throws Exception {
            // File类:以抽象的方式代表文件名和目录路径名
            File file = new File("d:\\good.xls");
            // 建立文件输入流
            FileInputStream fis = new FileInputStream(file);
            // 声明并创建一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook(fis);
            // sheet表示文件页,下标从0开始,表示第一页
            HSSFSheet sheet = workbook.getSheetAt(0);
            // 获取总行数(第一页)
            int rows = sheet.getPhysicalNumberOfRows();
            for (int i = 0; i < rows; i++) {
                // 先获取行对象,再操作列
                Row row = sheet.getRow(i);
                // 获取每一行的格子数(列数)
                int cols = row.getPhysicalNumberOfCells();
                for (int j = 0; j < cols; j++) {
                    // 获取格子对象
                    Cell cell = row.getCell(j);
                    // 输出格子对象
                    System.out.printf("%s\t", cell.toString());
                }
                // 换行输出
                System.out.println();
            }
        }
    

    文件截图+运行效果:
    在这里插入图片描述在这里插入图片描述
    细心的朋友会发现,0变成了0.0,1变成了1.0,这是因为POI默认数字为浮点数。数据类型稍微有点复杂,此处不深究,下面是修改后的完整代码:

    package ltd.newson.poi;
    
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    import java.io.File;
    import java.io.FileInputStream;
    
    /**
     * @Title: ReadExcel
     * @Author: newson.ltd
     * @Date: 2021-01-26 下午 12:01
     * @Version: 1.0
     * @Description: excel demo
     */
    public class ReadExcel {
    
        public static void main(String[] args) throws Exception {
            String fileName1 = "d:\\good.xls";
            String fileName2 = "d:\\good.xlsx";
            parseXls(fileName1);
            parseXlsx(fileName2);
        }
    
        /**
         * 读取xls格式excel
         * @param fileName
         * @throws Exception
         */
        private static void parseXls(String fileName) throws Exception {
            // 1、读取文件(逐层包装,装饰器模式)
            FileInputStream fis = new FileInputStream(new File(fileName));
            Workbook workbook = new HSSFWorkbook(fis);
            // 2、获取要处理的页面
            Sheet sheet = workbook.getSheetAt(0);
            // 3、处理单元格
            printCell(sheet);
    
        }
    
        /**
         * 读取xlsx格式excel
         * @param fileName
         * @throws Exception
         */
        private static void parseXlsx(String fileName) throws Exception {
            FileInputStream fis = new FileInputStream(new File(fileName));
            Workbook workbook = new XSSFWorkbook(fis);
            Sheet sheet = workbook.getSheetAt(0);
            printCell(sheet);
    
        }
    
        /**
         * 打印单元格
         * @param sheet
         */
        private static void printCell(Sheet sheet) {
            // 获取当前页的总行数
            int totalRowNums = sheet.getPhysicalNumberOfRows();
            for (int i = 0; i < totalRowNums; i++) {
                // 获取行
                Row row = sheet.getRow(i);
                // 获取列数(格子数)
                int cells = row.getPhysicalNumberOfCells();
                StringBuilder builder = new StringBuilder();
                for (int j = 0; j < cells; j++) {
                    Cell cell = row.getCell(j);
                    builder.append(getCellValue(cell)).append("\t");
                }
                System.out.print(builder.append("\n").toString());
            }
        }
    
        /**
         * 获取单元格的值,此处做简单处理
         * @param cell
         * @return
         */
        private static String getCellValue(Cell cell) {
            // 部分API已过时,此处是更新后的
            CellType cellType = cell.getCellTypeEnum();
            if (cellType == CellType.BOOLEAN) {
                return String.valueOf(cell.getBooleanCellValue());
            }
            if (cellType == CellType.NUMERIC) {
                return cell.getNumericCellValue() + "";
            }
            return cell.getStringCellValue();
        }
    
    }
    
    

    运行截图:
    在这里插入图片描述
    补充:注意getCellValue()中的API,有些教程可能会使用cell.getCellType()和Cell.CELL_TYPE_XXX(XXX表示数据类型),这些方法在新的POI中被标记为@deprecated(过时的),建议换成上述方法内的API。

    3、小结

    通过代码+注释的解读,会发现excel的读取是这么的简单,归纳一下操作步骤:

    • 输入目标文件,获取wordbook对象(工作簿)
    • 通过workbook对象获取sheet对象(要操作的页面)
    • 通过sheet对象获取当前页的总行数
    • 开循环,获取行对象,并通过行获取每一行的列数(格子数)
    • 再开个循环,通过行对象获取每一个格子对象
    • 操作格子对象(注意数据类型)

    最后一步也是比较复杂的一步,需要具体情况具体分析。本示例操作单页,多页同理。最后扩展一下excel单元格的数据类型:

    CellType含义
    _NONE未知类型
    NUMERIC数值类型(整数、小数、日期)
    STRING字符串
    FORMULA公式
    BLANK空白格(有样式)
    BOOLEAN布尔值
    ERROR错误单元格

    写在最后

    本次Java读取excel就介绍到这里啦,我是严光君,咱们下文再见~

    在这里插入图片描述
    创造不易,少侠请留步…… 动起可爱的双手,点个赞再走呗~ ٩(๑>◡<๑)۶

    展开全文
  • 基于注解(/src/test/java/modules/Student2.java) @ExcelField(title = "学号", order = 1) private Long id; @ExcelField(title = "姓名", order = 2) private String name; // 写入数据转换器 Student2...

    Excel4J v2.x

    一. v2.x新特性

    Excel读取支持部分类型转换了(如转为Integer,Long,Date(部分)等) v2.0.0之前只能全部内容转为String

    Excel支持非注解读取Excel内容了,内容存于List>对象内

    现在支持List>导出Excel了(可以不基于模板)

    Excel新增了Map数据样式映射功能(模板可为每个key设置一个样式,定义为:&key, 导出Map数据的样式将与key值映射)

    新增读取Excel数据转换器接口com.github.converter.ReadConvertible

    新增写入Excel数据转换器接口com.github.converter.WriteConvertible

    修复已知bug

    二. 基于注解(/src/test/java/modules/Student2.java)

    @ExcelField(title = "学号", order = 1)

    private Long id;

    @ExcelField(title = "姓名", order = 2)

    private String name;

    // 写入数据转换器 Student2DateConverter

    @ExcelField(title = "入学日期", order = 3, writeConverter = Student2DateConverter.class)

    private Date date;

    @ExcelField(title = "班级", order = 4)

    private Integer classes;

    // 读取数据转换器 Student2ExpelConverter

    @ExcelField(title = "是否开除", order = 5, readConverter = Student2ExpelConverter.class)

    private boolean expel;

    三. 读取Excel快速实现

    1.待读取Excel(截图)

    0b8bc5941c7ac657ab37cdf1056d64cc.png

    2. 读取转换器(/src/test/java/converter/Student2ExpelConverter.java)

    /**

    * excel是否开除 列数据转换器

    */

    public class Student2ExpelConverter implements ReadConvertible{

    @Override

    public Object execRead(String object) {

    return object.equals("是");

    }

    }

    3. 读取函数(/src/test/java/base/Excel2Module.java#excel2Object2)

    @Test

    public void excel2Object2() {

    String path = "D:\\JProject\\Excel4J\\src\\test\\resource\\students_02.xlsx";

    try {

    // 1)

    // 不基于注解,将Excel内容读至List>对象内

    List> lists = ExcelUtils.getInstance().readExcel2List(path, 1, 2, 0);

    System.out.println("读取Excel至String数组:");

    for (List list : lists) {

    System.out.println(list);

    }

    // 2)

    // 基于注解,将Excel内容读至List对象内

    // 验证读取转换函数Student2ExpelConverter

    // 注解 `@ExcelField(title = "是否开除", order = 5, readConverter = Student2ExpelConverter.class)`

    List students = ExcelUtils.getInstance().readExcel2Objects(path, Student2.class, 0, 0);

    System.out.println("读取Excel至对象数组(支持类型转换):");

    for (Student2 st : students) {

    System.out.println(st);

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    4. 读取结果

    读取Excel至String数组:

    [10000000000001, 张三, 2016/01/19, 101, 是]

    [10000000000002, 李四, 2017-11-17 10:19:10, 201, 否]

    读取Excel至对象数组(支持类型转换):

    Student2{id=10000000000001, name='张三', date=Tue Jan 19 00:00:00 CST 2016, classes=101, expel='true'}

    Student2{id=10000000000002, name='李四', date=Fri Nov 17 10:19:10 CST 2017, classes=201, expel='false'}

    Student2{id=10000000000004, name='王二', date=Fri Nov 17 00:00:00 CST 2017, classes=301, expel='false'}

    四. 导出Excel

    1. 不基于模板快速导出

    1) 导出函数(/src/test/java/base/Module2Excel.java#testList2Excel)

    @Test

    public void testList2Excel() throws Exception {

    List> list2 = new ArrayList<>();

    List header = new ArrayList<>();

    for (int i = 0; i < 10; i++) {

    List _list = new ArrayList<>();

    for (int j = 0; j < 10; j++) {

    _list.add(i + " -- " + j);

    }

    list2.add(_list);

    header.add(i + "---");

    }

    ExcelUtils.getInstance().exportObjects2Excel(list2, header, "D:/D.xlsx");

    }

    2) 导出效果(截图)

    324191821ad606280f56582f1818a0a2.png

    2. 带有写入转换器函数的导出

    1) 转换器(/src/test/java/converter/Student2DateConverter.java)

    /**

    * 导出excel日期数据转换器

    */

    public class Student2DateConverter implements WriteConvertible {

    @Override

    public Object execWrite(Object object) {

    Date date = (Date) object;

    return DateUtils.date2Str(date, DateUtils.DATE_FORMAT_MSEC_T_Z);

    }

    }

    2)导出函数(/src/test/java/base/Module2Excel.java#testWriteConverter)

    // 验证日期转换函数 Student2DateConverter

    // 注解 `@ExcelField(title = "入学日期", order = 3, writeConverter = Student2DateConverter.class)`

    @Test

    public void testWriteConverter() throws Exception {

    List list = new ArrayList<>();

    for (int i = 0; i < 10; i++) {

    list.add(new Student2(10000L + i, "学生" + i, new Date(), 201, false));

    }

    ExcelUtils.getInstance().exportObjects2Excel(list, Student2.class, true, "sheet0", true, "D:/D.xlsx");

    }

    3) 导出效果(截图)

    5d3492d2808011415138d1c6ae057ce6.png

    3. 基于模板List导出

    1) 导出函数(/src/test/java/base/Module2Excel.java#testObject2Excel)

    @Test

    public void testObject2Excel() throws Exception {

    String tempPath = "/normal_template.xlsx";

    List list = new ArrayList<>();

    list.add(new Student1("1010001", "盖伦", "六年级三班"));

    list.add(new Student1("1010002", "古尔丹", "一年级三班"));

    list.add(new Student1("1010003", "蒙多(被开除了)", "六年级一班"));

    list.add(new Student1("1010004", "萝卜特", "三年级二班"));

    list.add(new Student1("1010005", "奥拉基", "三年级二班"));

    list.add(new Student1("1010006", "得嘞", "四年级二班"));

    list.add(new Student1("1010007", "瓜娃子", "五年级一班"));

    list.add(new Student1("1010008", "战三", "二年级一班"));

    list.add(new Student1("1010009", "李四", "一年级一班"));

    Map data = new HashMap<>();

    data.put("title", "战争学院花名册");

    data.put("info", "学校统一花名册");

    // 基于模板导出Excel

    ExcelUtils.getInstance().exportObjects2Excel(tempPath, 0, list, data, Student1.class, false, "D:/A.xlsx");

    // 不基于模板导出Excel

    ExcelUtils.getInstance().exportObjects2Excel(list, Student1.class, true, null, true, "D:/B.xlsx");

    }

    2) 导出模板(截图)

    be64f08220391947edd0315cb7cc6170.png

    3) 基于模板导出结果(截图)

    709db5205a49fbf21784419753b89f6d.png

    4) 不基于模板导出结果(截图)

    0fea5ca6b64fa728027c93fea9118ee9.png

    4. 基于模板Map>导出

    1) 导出函数(/src/test/java/base/Module2Excel.java#testMap2Excel)

    @Test

    public void testMap2Excel() throws Exception {

    Map classes = new HashMap<>();

    Map data = new HashMap<>();

    data.put("title", "战争学院花名册");

    data.put("info", "学校统一花名册");

    classes.put("class_one", new ArrayList() {{

    add(new Student1("1010009", "李四", "一年级一班"));

    add(new Student1("1010002", "古尔丹", "一年级三班"));

    }});

    classes.put("class_two", new ArrayList() {{

    add(new Student1("1010008", "战三", "二年级一班"));

    }});

    classes.put("class_three", new ArrayList() {{

    add(new Student1("1010004", "萝卜特", "三年级二班"));

    add(new Student1("1010005", "奥拉基", "三年级二班"));

    }});

    classes.put("class_four", new ArrayList() {{

    add(new Student1("1010006", "得嘞", "四年级二班"));

    }});

    classes.put("class_six", new ArrayList() {{

    add(new Student1("1010001", "盖伦", "六年级三班"));

    add(new Student1("1010003", "蒙多", "六年级一班"));

    }});

    ExcelUtils.getInstance().exportObject2Excel("/map_template.xlsx",

    0, classes, data, Student1.class, false, "D:/C.xlsx");

    }

    2) 导出模板(截图)

    bf329e1b7223b6ea004219863e0037e8.png

    3) 导出结果(截图)

    b6f9aeeaff2d93a7851038bd2ed5b53e.png

    五. 使用(JDK1.7及以上)

    1) github拷贝项目

    git clone https://github.com/Crab2died/Excel4J.git Excel4J

    2) 最新版本maven 引用:

    com.github.crab2died

    Excel4J

    2.1.0

    六. 开源协议:Apache-2.0

    七. 链接

    github -> github地址

    码云 -> 码云

    展开全文
  • 转自Java POI 导出Excel经典实现 导出Excel弹出下载框 Spring Boot【不定期更新】_兰染-CSDN博客_java poi导出excel 在web开发中,有一个经典的功能,就是数据的导入导出。特别是数据的导出,在生产管理或者财务...

    转自Java POI 导出Excel经典实现 导出Excel弹出下载框 Spring Boot【不定期更新】_兰染-CSDN博客_java poi导出excel

    在web开发中,有一个经典的功能,就是数据的导入导出。特别是数据的导出,在生产管理或者财务系统中用的非常普遍,因为这些系统经常要做一些报表打印的工作。而数据导出的格式一般是EXCEL或者PDF,我这里就用两篇文章分别给大家介绍下。(注意,我们这里说的数据导出可不是数据库中的数据导出!么误会啦^_^)

             呵呵,首先我们来导出EXCEL格式的文件吧。现在主流的操作Excel文件的开源工具有很多,用得比较多的就是Apache的POI及JExcelAPI。这里我们用Apache POI!我们先去Apache的大本营下载POI的jar包:http://poi.apache.org/ ,我这里使用的是3.0.2版本。

            将3个jar包导入到classpath下,什么?忘了怎么导包?不会吧!好,我们来写一个导出Excel的实用类(所谓实用,是指基本不用怎么修改就可以在实际项目中直接使用的!)。我一直强调做类也好,做方法也好,一定要通用性和灵活性强。下面这个类就算基本贯彻了我的这种思想。那么,熟悉许老师风格的人应该知道,这时候该要甩出一长串代码了。没错,大伙请看:

    复制代码

     1 import java.util.Date;
     2 
     3 public class Student
     4 {
     5     private long id;
     6     private String name;
     7     private int age;
     8     private boolean sex;
     9     private Date birthday;
    10 
    11     public Student()
    12     {
    13     }
    14 
    15     public Student(long id, String name, int age, boolean sex, Date birthday)
    16     {
    17         this.id = id;
    18         this.name = name;
    19         this.age = age;
    20         this.sex = sex;
    21         this.birthday = birthday;
    22     }
    23 
    24     public long getId()
    25     {
    26         return id;
    27     }
    28 
    29     public void setId(long id)
    30     {
    31         this.id = id;
    32     }
    33 
    34     public String getName()
    35     {
    36         return name;
    37     }
    38 
    39     public void setName(String name)
    40     {
    41         this.name = name;
    42     }
    43 
    44     public int getAge()
    45     {
    46         return age;
    47     }
    48 
    49     public void setAge(int age)
    50     {
    51         this.age = age;
    52     }
    53 
    54     public boolean getSex()
    55     {
    56         return sex;
    57     }
    58 
    59     public void setSex(boolean sex)
    60     {
    61         this.sex = sex;
    62     }
    63 
    64     public Date getBirthday()
    65     {
    66         return birthday;
    67     }
    68 
    69     public void setBirthday(Date birthday)
    70     {
    71         this.birthday = birthday;
    72     }
    73 
    74 }

    复制代码

    复制代码

     1 public class Book
     2 {
     3     private int bookId;
     4     private String name;
     5     private String author;
     6     private float price;
     7     private String isbn;
     8     private String pubName;
     9     private byte[] preface;
    10 
    11     public Book()
    12     {
    13     }
    14 
    15     public Book(int bookId, String name, String author, float price,
    16             String isbn, String pubName, byte[] preface)
    17     {
    18         this.bookId = bookId;
    19         this.name = name;
    20         this.author = author;
    21         this.price = price;
    22         this.isbn = isbn;
    23         this.pubName = pubName;
    24         this.preface = preface;
    25     }
    26 
    27     public int getBookId()
    28     {
    29         return bookId;
    30     }
    31 
    32     public void setBookId(int bookId)
    33     {
    34         this.bookId = bookId;
    35     }
    36 
    37     public String getName()
    38     {
    39         return name;
    40     }
    41 
    42     public void setName(String name)
    43     {
    44         this.name = name;
    45     }
    46 
    47     public String getAuthor()
    48     {
    49         return author;
    50     }
    51 
    52     public void setAuthor(String author)
    53     {
    54         this.author = author;
    55     }
    56 
    57     public float getPrice()
    58     {
    59         return price;
    60     }
    61 
    62     public void setPrice(float price)
    63     {
    64         this.price = price;
    65     }
    66 
    67     public String getIsbn()
    68     {
    69         return isbn;
    70     }
    71 
    72     public void setIsbn(String isbn)
    73     {
    74         this.isbn = isbn;
    75     }
    76 
    77     public String getPubName()
    78     {
    79         return pubName;
    80     }
    81 
    82     public void setPubName(String pubName)
    83     {
    84         this.pubName = pubName;
    85     }
    86 
    87     public byte[] getPreface()
    88     {
    89         return preface;
    90     }
    91 
    92     public void setPreface(byte[] preface)
    93     {
    94         this.preface = preface;
    95     }
    96 }

    复制代码

    上面这两个类一目了然,就是两个简单的javabean风格的类。再看下面真正的重点类:

    复制代码

    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import javax.swing.JOptionPane;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
    import org.apache.poi.hssf.usermodel.HSSFComment;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.usermodel.HSSFPatriarch;
    import org.apache.poi.hssf.usermodel.HSSFRichTextString;
    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.hssf.util.HSSFColor;
    
    /**
     * 利用开源组件POI3.0.2动态导出EXCEL文档 转载时请保留以下信息,注明出处!
     * 
     * @author leno
     * @version v1.0
     * @param <T>
     *            应用泛型,代表任意一个符合javabean风格的类
     *            注意这里为了简单起见,boolean型的属性xxx的get器方式为getXxx(),而不是isXxx()
     *            byte[]表jpg格式的图片数据
     */
    public class ExportExcel<T>
    {
        public void exportExcel(Collection<T> dataset, OutputStream out)
        {
            exportExcel("测试POI导出EXCEL文档", null, dataset, out, "yyyy-MM-dd");
        }
    
        public void exportExcel(String[] headers, Collection<T> dataset,
                OutputStream out)
        {
            exportExcel("测试POI导出EXCEL文档", headers, dataset, out, "yyyy-MM-dd");
        }
    
        public void exportExcel(String[] headers, Collection<T> dataset,
                OutputStream out, String pattern)
        {
            exportExcel("测试POI导出EXCEL文档", headers, dataset, out, pattern);
        }
    
        /**
         * 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
         * 
         * @param title
         *            表格标题名
         * @param headers
         *            表格属性列名数组
         * @param dataset
         *            需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的
         *            javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
         * @param out
         *            与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
         * @param pattern
         *            如果有时间数据,设定输出格式。默认为"yyy-MM-dd"
         */
        @SuppressWarnings("unchecked")
        public void exportExcel(String title, String[] headers,
                Collection<T> dataset, OutputStream out, String pattern)
        {
            // 声明一个工作薄
            HSSFWorkbook workbook = new HSSFWorkbook();
            // 生成一个表格
            HSSFSheet sheet = workbook.createSheet(title);
            // 设置表格默认列宽度为15个字节
            sheet.setDefaultColumnWidth((short) 15);
            // 生成一个样式
            HSSFCellStyle style = workbook.createCellStyle();
            // 设置这些样式
            style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
            style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            // 生成一个字体
            HSSFFont font = workbook.createFont();
            font.setColor(HSSFColor.VIOLET.index);
            font.setFontHeightInPoints((short) 12);
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            // 把字体应用到当前的样式
            style.setFont(font);
            // 生成并设置另一个样式
            HSSFCellStyle style2 = workbook.createCellStyle();
            style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
            style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
            style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
            style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
            // 生成另一个字体
            HSSFFont font2 = workbook.createFont();
            font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
            // 把字体应用到当前的样式
            style2.setFont(font2);
    
            // 声明一个画图的顶级管理器
            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
            // 定义注释的大小和位置,详见文档
            HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0,
                    0, 0, 0, (short) 4, 2, (short) 6, 5));
            // 设置注释内容
            comment.setString(new HSSFRichTextString("可以在POI中添加注释!"));
            // 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
            comment.setAuthor("leno");
    
            // 产生表格标题行
            HSSFRow row = sheet.createRow(0);
            for (short i = 0; i < headers.length; i++)
            {
                HSSFCell cell = row.createCell(i);
                cell.setCellStyle(style);
                HSSFRichTextString text = new HSSFRichTextString(headers[i]);
                cell.setCellValue(text);
            }
    
            // 遍历集合数据,产生数据行
            Iterator<T> it = dataset.iterator();
            int index = 0;
            while (it.hasNext())
            {
                index++;
                row = sheet.createRow(index);
                T t = (T) it.next();
                // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
                Field[] fields = t.getClass().getDeclaredFields();
                for (short i = 0; i < fields.length; i++)
                {
                    HSSFCell cell = row.createCell(i);
                    cell.setCellStyle(style2);
                    Field field = fields[i];
                    String fieldName = field.getName();
                    String getMethodName = "get"
                            + fieldName.substring(0, 1).toUpperCase()
                            + fieldName.substring(1);
                    try
                    {
                        Class tCls = t.getClass();
                        Method getMethod = tCls.getMethod(getMethodName,
                                new Class[]
                                {});
                        Object value = getMethod.invoke(t, new Object[]
                        {});
                        // 判断值的类型后进行强制类型转换
                        String textValue = null;
                        // if (value instanceof Integer) {
                        // int intValue = (Integer) value;
                        // cell.setCellValue(intValue);
                        // } else if (value instanceof Float) {
                        // float fValue = (Float) value;
                        // textValue = new HSSFRichTextString(
                        // String.valueOf(fValue));
                        // cell.setCellValue(textValue);
                        // } else if (value instanceof Double) {
                        // double dValue = (Double) value;
                        // textValue = new HSSFRichTextString(
                        // String.valueOf(dValue));
                        // cell.setCellValue(textValue);
                        // } else if (value instanceof Long) {
                        // long longValue = (Long) value;
                        // cell.setCellValue(longValue);
                        // }
                        if (value instanceof Boolean)
                        {
                            boolean bValue = (Boolean) value;
                            textValue = "男";
                            if (!bValue)
                            {
                                textValue = "女";
                            }
                        }
                        else if (value instanceof Date)
                        {
                            Date date = (Date) value;
                            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                            textValue = sdf.format(date);
                        }
                        else if (value instanceof byte[])
                        {
                            // 有图片时,设置行高为60px;
                            row.setHeightInPoints(60);
                            // 设置图片所在列宽度为80px,注意这里单位的一个换算
                            sheet.setColumnWidth(i, (short) (35.7 * 80));
                            // sheet.autoSizeColumn(i);
                            byte[] bsValue = (byte[]) value;
                            HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0,
                                    1023, 255, (short) 6, index, (short) 6, index);
                            anchor.setAnchorType(2);
                            patriarch.createPicture(anchor, workbook.addPicture(
                                    bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG));
                        }
                        else
                        {
                            // 其它数据类型都当作字符串简单处理
                            textValue = value.toString();
                        }
                        // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
                        if (textValue != null)
                        {
                            Pattern p = Pattern.compile("^//d+(//.//d+)?$");
                            Matcher matcher = p.matcher(textValue);
                            if (matcher.matches())
                            {
                                // 是数字当作double处理
                                cell.setCellValue(Double.parseDouble(textValue));
                            }
                            else
                            {
                                HSSFRichTextString richString = new HSSFRichTextString(
                                        textValue);
                                HSSFFont font3 = workbook.createFont();
                                font3.setColor(HSSFColor.BLUE.index);
                                richString.applyFont(font3);
                                cell.setCellValue(richString);
                            }
                        }
                    }
                    catch (SecurityException e)
                    {
                        e.printStackTrace();
                    }
                    catch (NoSuchMethodException e)
                    {
                        e.printStackTrace();
                    }
                    catch (IllegalArgumentException e)
                    {
                        e.printStackTrace();
                    }
                    catch (IllegalAccessException e)
                    {
                        e.printStackTrace();
                    }
                    catch (InvocationTargetException e)
                    {
                        e.printStackTrace();
                    }
                    finally
                    {
                        // 清理资源
                    }
                }
            }
            try
            {
                workbook.write(out);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args)
        {
            // 测试学生
            ExportExcel<Student> ex = new ExportExcel<Student>();
            String[] headers =
            { "学号", "姓名", "年龄", "性别", "出生日期" };
            List<Student> dataset = new ArrayList<Student>();
            dataset.add(new Student(10000001, "张三", 20, true, new Date()));
            dataset.add(new Student(20000002, "李四", 24, false, new Date()));
            dataset.add(new Student(30000003, "王五", 22, true, new Date()));
            // 测试图书
            ExportExcel<Book> ex2 = new ExportExcel<Book>();
            String[] headers2 =
            { "图书编号", "图书名称", "图书作者", "图书价格", "图书ISBN", "图书出版社", "封面图片" };
            List<Book> dataset2 = new ArrayList<Book>();
            try
            {
                BufferedInputStream bis = new BufferedInputStream(
                        new FileInputStream("V://book.bmp"));
                byte[] buf = new byte[bis.available()];
                while ((bis.read(buf)) != -1)
                {
                    //
                }
                dataset2.add(new Book(1, "jsp", "leno", 300.33f, "1234567",
                        "清华出版社", buf));
                dataset2.add(new Book(2, "java编程思想", "brucl", 300.33f, "1234567",
                        "阳光出版社", buf));
                dataset2.add(new Book(3, "DOM艺术", "lenotang", 300.33f, "1234567",
                        "清华出版社", buf));
                dataset2.add(new Book(4, "c++经典", "leno", 400.33f, "1234567",
                        "清华出版社", buf));
                dataset2.add(new Book(5, "c#入门", "leno", 300.33f, "1234567",
                        "汤春秀出版社", buf));
    
                OutputStream out = new FileOutputStream("E://a.xls");
                OutputStream out2 = new FileOutputStream("E://b.xls");
                ex.exportExcel(headers, dataset, out);
                ex2.exportExcel(headers2, dataset2, out2);
                out.close();
                JOptionPane.showMessageDialog(null, "导出成功!");
                System.out.println("excel导出成功!");
            }
            catch (FileNotFoundException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

    复制代码

     写完之后,如果您不是用eclipse工具生成的Servlet,千万别忘了在web.xml上注册这个Servelt。而且同样的,拷贝一张小巧的图书图片命名为book.jpg放置到当前WEB根目录的/WEB-INF/下。部署好web工程,用浏览器访问Servlet看下效果吧!是不是下载成功了。呵呵,您可以将下载到本地的excel报表用打印机打印出来,这样您就大功告成了。完事了我们就思考:我们发现,我们做的方法,不管是本地调用,还是在WEB服务器端用Servlet调用;不管是输出学生列表,还是图书列表信息,代码都几乎一样,而且这些数据我们很容器结合后台的DAO操作数据库动态获取。恩,类和方法的通用性和灵活性开始有点感觉了。好啦,祝您学习愉快!

    简单版 无excel格式样式设置  及excel下载

    复制代码

      1 package com.howbuy.uaa.utils;
      2 
      3 import java.io.BufferedInputStream;
      4 import java.io.BufferedOutputStream;
      5 import java.io.File;
      6 import java.io.FileInputStream;
      7 import java.io.IOException;
      8 import java.io.InputStream;
      9 import java.io.OutputStream;
     10 import java.lang.reflect.Field;
     11 import java.lang.reflect.InvocationTargetException;
     12 import java.lang.reflect.Method;
     13 import java.text.SimpleDateFormat;
     14 import java.util.Collection;
     15 import java.util.Date;
     16 import java.util.Iterator;
     17 import java.util.regex.Matcher;
     18 import java.util.regex.Pattern;
     19 
     20 import javax.servlet.http.HttpServletResponse;
     21 
     22 import org.apache.poi.hssf.usermodel.HSSFCell;
     23 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
     24 import org.apache.poi.hssf.usermodel.HSSFFont;
     25 import org.apache.poi.hssf.usermodel.HSSFRichTextString;
     26 import org.apache.poi.hssf.usermodel.HSSFRow;
     27 import org.apache.poi.hssf.usermodel.HSSFSheet;
     28 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
     29 
     30 
     31 public class ExportExcel<T> {
     32     public void exportExcel(String title,Collection<T> dataset, OutputStream out) {
     33         exportExcel(title, null, dataset, out, "yyyy-MM-dd");
     34     }
     35 
     36     public void exportExcel(String title,String[] headers, Collection<T> dataset,
     37             OutputStream out) {
     38         exportExcel(title, headers, dataset, out, "yyyy-MM-dd");
     39     }
     40     
     41     @SuppressWarnings("unchecked")
     42     public void exportExcel(String title, String[] headers,Collection<T> dataset, OutputStream out, String pattern) {
     43         // 声明一个工作薄
     44         HSSFWorkbook workbook = new HSSFWorkbook();
     45         // 生成一个表格
     46         HSSFSheet sheet = workbook.createSheet(title);
     47         // 设置表格默认列宽度为15个字节
     48         sheet.setDefaultColumnWidth((short) 15);
     49         // 生成一个样式
     50         HSSFCellStyle style = workbook.createCellStyle();
     51         // 生成一个字体
     52         HSSFFont font = workbook.createFont();
     53         font.setFontHeightInPoints((short) 12);
     54         // 把字体应用到当前的样式
     55         style.setFont(font);
     56         // 产生表格标题行
     57         HSSFRow row = sheet.createRow(0);
     58         for (short i = 0; i < headers.length; i++) {
     59             HSSFCell cell = row.createCell(i);
     60             cell.setCellStyle(style);
     61             HSSFRichTextString text = new HSSFRichTextString(headers[i]);
     62             cell.setCellValue(text);
     63         }
     64         // 遍历集合数据,产生数据行
     65         Iterator<T> it = dataset.iterator();
     66         int index = 0;
     67         while (it.hasNext()) {
     68             index++;
     69             row = sheet.createRow(index);
     70             T t = (T) it.next();
     71             // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
     72             Field[] fields = t.getClass().getDeclaredFields();
     73             for (short i = 0; i < fields.length; i++) {
     74                 HSSFCell cell = row.createCell(i);
     75                 cell.setCellStyle(style);
     76                 Field field = fields[i];
     77                 String fieldName = field.getName();
     78                 String getMethodName = "get"
     79                         + fieldName.substring(0, 1).toUpperCase()
     80                         + fieldName.substring(1);
     81                 try {
     82                     Class tCls = t.getClass();
     83                     Method getMethod = tCls.getMethod(getMethodName,
     84                             new Class[] {});
     85                     Object value = getMethod.invoke(t, new Object[] {});
     86                     // 判断值的类型后进行强制类型转换
     87                     String textValue = null;
     88                      if (value instanceof Integer) {
     89                          int intValue = (Integer) value;
     90                          cell.setCellValue(intValue);
     91                      }
     92                      else if (value instanceof Long) {
     93                          long longValue = (Long) value;
     94                          cell.setCellValue(longValue);
     95                      }
     96                      else if (value instanceof Boolean) {
     97                         boolean bValue = (Boolean) value;
     98                         textValue = "1";
     99                         if (!bValue) {
    100                             textValue = "0";
    101                         }
    102                     } else if (value instanceof Date) {
    103                         Date date = (Date) value;
    104                         SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    105                         textValue = sdf.format(date);
    106                     } else {
    107                         // 其它数据类型都当作字符串简单处理
    108                         if(value == null)
    109                         {
    110                             textValue = "";
    111                         }
    112                         else {
    113                             textValue = value.toString();
    114                         }
    115                             
    116                     }
    117                     
    118                     if (textValue != null) {
    119                         Pattern p = Pattern.compile("^//d+(//.//d+)?$");
    120                         Matcher matcher = p.matcher(textValue);
    121                         if (matcher.matches()) {
    122                             // 是数字当作double处理
    123                             cell.setCellValue(Double.parseDouble(textValue));
    124                         } else {
    125                             HSSFRichTextString richString = new HSSFRichTextString(
    126                                     textValue);
    127                             richString.applyFont(font);
    128                             cell.setCellValue(richString);
    129                         }
    130                     }
    131                 } catch (SecurityException e) {
    132                     e.printStackTrace();
    133                 } catch (NoSuchMethodException e) {
    134                     e.printStackTrace();
    135                 } catch (IllegalArgumentException e) {
    136                     e.printStackTrace();
    137                 } catch (IllegalAccessException e) {
    138                     e.printStackTrace();
    139                 } catch (InvocationTargetException e) {
    140                     e.printStackTrace();
    141                 } finally {
    142                     // 清理资源
    143                 }
    144             }
    145 
    146         }
    147         try {
    148             workbook.write(out);
    149         } catch (IOException e) {
    150             e.printStackTrace();
    151         }
    152     }
    153     
    154     public void downloadExcel(String path, HttpServletResponse response) {
    155         try {
    156             // path是指欲下载的文件的路径。
    157             File file = new File(path);
    158             String name = file.getName();
    159             // 取得文件名。
    160             String filename = java.net.URLEncoder.encode(name,"utf-8");
    161             // 清空response
    162             response.reset();
    163             // 设置response的Header
    164             response.addHeader("Content-Disposition", "attachment;filename="
    165                     + new String(filename.getBytes()));
    166             response.addHeader("Content-Length", "" + file.length());
    167             OutputStream toClient = new BufferedOutputStream(
    168                     response.getOutputStream());
    169             response.setContentType("application/ms-excel;charset=gb2312");
    170             // 以流的形式下载文件。
    171             InputStream fis = new BufferedInputStream(new FileInputStream(path));
    172             byte[] buffer = new byte[fis.available()];
    173             fis.read(buffer);
    174             fis.close();
    175             toClient.write(buffer);
    176             toClient.flush();
    177             toClient.close();
    178         } catch (IOException ex) {
    179             ex.printStackTrace();
    180         }
    181     }
    182 }
    展开全文
  • java使用poi在word模板中替换柱状图、折线图、饼图、表格、文本、图片
  • 首先导入poi工具所需的依赖包 &lt;!--POI操作excel--&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.poi&lt;/groupId&gt; &lt;artifactId&gt;p...
  • java poi 操作word文本,图表,遇到的问题直接上问题模板字段匹配问题图表问题 之前做过 一期 poi操作world 的文章. 然后前一段因为工作要求改版,改了很多很多版,模板也花里胡哨了,今天就把我出文章之后又遇到的...
  • java通过poi-tl生成表格以及源码分析依赖模板如何动态生成表格参考文档及分析代码 最近导出的word文件要求是越来越多了,而且对样式也做了很多要求,今天参考文档学习了一下普通表格构建表格、动态构建word表格的...
  • JAVA替换Word模板指定字符,并可插入图片。 之前有写过一篇使用jacob对word插入图片的博客。点击率蛮高8800多次,当然多亏了百度搜索引擎的帮忙???? 但是小编在使用以前写的代码走了一遍流程时,发现代码貌似会报错...
  • package ...import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.text.Forma...
  • Javapoi导入导出Excel

    2021-05-11 18:24:35
    前言 1、将用户信息导出为excel表格...操作Excel目前比较流行的就是Apache POI和 阿里巴巴的easyExcel! 接下来说说Apache下的POI吧 <dependencies> <!--xls(03)--> <dependency> <gr...
  • java poi设置单元格样式

    千次阅读 2018-03-21 09:54:44
    // 可以继承于某一个样式,样式重复的,后面的样式会覆盖前面的样式 style .cloneStyleFrom (styles .get ( "base" )) ; style .setAlignment (HorizontalAlignment .LEFT ) ; style .setVerticalAlignment ...
  • 只好发挥我一年多面向百度编程的经验一顿查,踩了好多坑最后确定了还是使用Apache poi工具,咱程序员呐,可以当时写不出来但是一定得会面向百度编程????????。 从网上找了一些POI工具介绍 Apache poi的hwpf模块是...
  • excel文件导入导出,poi是比较常用的框架,最近经常用到...maven继承 <!--Excel begin --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId>
  • 使用写入excel工具类的例子 说明:改工具类是网上公开的,来源现在找不着了,我只是在原基础上修改了下,抽离了泛型。如有侵权,请通知博主 工具类代码: ... import java.io.FileInputStream;...import java
  • 需求 将后台系统中的二维码导出到word中,数据库保存的图片的路径 效果 dependency ...org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2<
  • 第一步,继承XWPFDocument,写一个操作图片写入大小、位置的方法, 如果没有此方法,图片写入不会报错,但是打开Word文档,会看不到图片: package word; import java.io.IOException; import java.io....
  • Java POI(一)

    2020-07-26 21:07:49
    Java POI-3.17 单元格相关 文本格式 通常,Excel的单元格格式能够根据输入的值进行智能转换(其实没那么智能),所以更多的 是在智能转换不满足需求时,需要手动规范单元格格式,即自定义格式。 CellStyle通过...
  • JavaPOI读取Excel的两种模式

    千次阅读 2020-05-19 10:58:15
    POI下usermodel相关包,它对用户友好,在ss包下有统一的接口,但它是把整个文件读取到内存中的,对于大量数据很容易导致内存溢出,所以只能用来处理相对较小量的数据 示例代码 public static List<Map<String,...
  • 这个是我写的简单的导出excel 注意引入的都是poi的包,使用Cell,excel2003的.xls对应是HSSFCell,而之后的xlsx对应的则是XSSFCell,但是他们都继承于Cell,所以使用Cell就可以使用两种格式的excel导入了,下面解决...
  • 二、java对word文件的解析 2.1 引入所需要的jar包 org.apache.poi poi-scratchpad 4.1.2 org.apache.poi poi-ooxml 4.1.2 2.2常用方法 HWPFDocument(文档类): xd.characterLength(); //返回文档的字符长度。 xd....
  • Java poi 导出excel

    2020-09-04 11:11:09
    POI依赖: <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency>
  • >>号外:关注“Java精选”公众号,菜单栏->聚合->干货分享,回复关键词领取视频资料、开源项目。1. Excel2003与Excel2007两个版本的最大行数和...
  • Java 使用 POI 3.17根据Word 模板替换、操作书签

    万次阅读 热门讨论 2018-04-09 12:04:58
    查找了大量的文档发现很多的博客对这个进行了介绍,主要有2种方案做处理,jacob 和poi。但是现在的服务器基本上是部署在Linux上,所以jacob基本上是不可行的。所以呢,主要是使用poi来进行这些操作。 Apache poi的...
  • java 使用POI操作word获取样式

    千次阅读 2019-10-15 17:09:20
    XWPFDocument对象也就是我们所说的word文档对象,只有拥有此对象你才能操作word,poi实际上是将word解析成一个xml然后在读取里面的内容,所以你在操作word之前必须对一些概念有一定的了解,否则也是寸步难行。...
  • 若不是为了继承C语言,它也不会出现在C++中(虽说,union在C++中得到了扩充,完成了接近类的功能).它的作用主要是节省内存空间,在嵌 ... 依赖注入及AOP简述(五)——依赖注入的方式 . 二.依赖注入的应用模式 前面我们...
  • import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import jav...
  • 一、因为原本的XWPFDocument类插入图片方法有bug,要么打不开word,要么打开了不显示图片,所以新建一个CustomXWPFDocument类继承XWPFDocument,重写插入图片方法。插入图片默认为嵌入型,这里提供浮于文字上方方法...
  • Java ArrayList和继承

    2020-07-14 08:54:49
    Java ArrayList和继承 1. Math类(方法补充及复习) 2. ArrayList类 2.1 什么是ArrayList 2.2 ArrayList的使用步骤 2.3 基本数据类型对应的引用类型 2.4 常用API 2.5 代码部分 3. 继承 3.1 继承的定义 3.2 继承的...
  • Java poi Word模板数据替换需求说明设计思路功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,871
精华内容 2,348
关键字:

java继承poi

java 订阅