我是靠谱客的博主 任性星星,最近开发中收集的这篇文章主要介绍Java读取Excel文件汇总,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

相信很多程序猿朋友碰到上传、读取Excel文件的问题,做个小结,权当是笔记收着吧。

         之前做金融报表,是把Excel内嵌到页面中的,技术上采用ZK结合POI读取和插入Excel数据,后台方法比较死,比较程式化。

         目前新需求是把Excel表格上传到服务器,读取到里边的数据做处理。

   一、首先上传Excel

   1、页面添加文件域

 

Java代码 
  1. <form id="uploadExcel" action="/auth/user/toHandleBatchRobotExcel.do"  
  2.  enctype="multipart/form- data" method="POST" >  
  3.    <input type="file" id="excel" name="excelFile"/>  
  4.    <input type="button" id="uploadExcel" />  
  5. </form>  

 

   2、使用ajax提交表单(需导入jquery.form.js)

 

Java代码 
  1. var excel=$("#excel").val();  
  2. var location=$('#excel').val();  
  3. var point = location.lastIndexOf(".");  
  4. var type = location.substr(point);  
  5. //type是Excel表格的格式.xls.xlsx  
  6. $("#uploadExcel").ajaxSubmit({  
  7.       data:{ext:type},  
  8.       success:function(data){  
  9.       var dataJson = eval("("+data+")");  
  10.       console.log(data);  
  11.       if(dataJson.code==100){  
  12.            alert(dataJson.message);  
  13.       }else{  
  14.            alert("成功上传"+dataJson.attribute.robotNum+"条记录");  
  15.       }  
  16.     }  
  17.  });  

 

 

 二、后台读取

 

   我尝试了两种方式来读取,jxl和poi。

  1、jxl读取

   jxl操作也是比较方便的,上代码吧。

   Jar包:jxl-2.6.jar

   读取Excel:

Java代码 
  1. @RequestMapping(value = UrlMappings.HANDLE_BATCH_ROBOT_EXCEL, method = RequestMethod.POST)  
  2. @ResponseBody  
  3.     public void handleExcel(HttpServletResponse response,  
  4.           MultipartHttpServletRequest request, String ext) {  
  5.               logger.info("处理Excel表格");  
  6.               logger.info("开始解析...");  
  7.               logger.info(ext);  
  8.        
  9. MultipartFile fileFile = request.getFile("excelFile");  
  10. InputStream in = fileFile.getInputStream();  
  11. //获取Excel文件对象  
  12. Workbook wb = Workbook.getWorkbook(in);  
  13. //获取文件的指定工作表默认的第一个  
  14. Sheet sheet = wb.getSheet(0);  
  15. // 单元格  
  16. Cell cell;  
  17. //获取行数  
  18. Int rows = sheet.getRows();  
  19. Map<Integer, String> map = new HashMap<Integer, String>();  
  20. List<UserInfoVo> list = new LinkedList<UserInfoVo>();  
  21.   
  22. if (rows.size() > 0 && rows!= null) {  
  23.    for (int i = 1; i < rows.size(); i++) {  
  24.       for (int j = 0; j < sheet.getColumns(); j++) {  
  25.          cell =sheet.getCell(j,i);  
  26.          map.put(j,cell.getContents());  
  27.       }  
  28.       //Excel数据对应的实体类,根据情况自己设定  
  29.       UserInfoVo userInfoVo = new UserInfoVo();  
  30.       userInfoVo.setNickName(map.get(1));  
  31.       userInfoVo.setGender(map.get(2).equals("男") ? 0 : 1);  
  32.       userInfoVo.setBirthday(sdf.parse(map.get(3)).getTime());  
  33.       userInfoVo.setRegisterDatetime(sdf.parse(map.get(4))  
  34.             .getTime());  
  35.       userInfoVo.setState(1);  
  36.       list.add(userInfoVo);  
  37.    }  
  38. }  
  39. }  

    这样读取到的list中就包括了excel表中的各行数据。

    但是在使用过程中发现,有些用户上传2007版的Excel表格,这样的话就会出现读取错误的情况

    jxl.read.biff.BiffException: Unable to recognize OLE stream,这是因为jxl久未更新,没法读取新版本的         Excel,就是.xlsx格式的文件。

 

    于是,换种思路,使用兼容性更好的poi进行读取。

      

    2、poi读取

 

    poi是读取Excel最佳工具,功能丰富,对读取不同版本的excel都做了对应处理。

    jar包:

    poi-3.11.jar  针对03版excel,即后缀为.xls的文件。 

    poi-ooxml-3.11.jar  针对07版excel,即后缀为.xlsx的文件。

         

    读取Excel: 

Java代码 
  1. @RequestMapping(value = UrlMappings.HANDLE_BATCH_ROBOT_EXCEL, method = RequestMethod.POST)  
  2. @ResponseBody  
  3. public void handleExcel(HttpServletResponse response,  
  4.       MultipartHttpServletRequest request, String ext) {  
  5.    logger.info("处理Excel表格");  
  6.    logger.info("开始解析...");  
  7.    //excel格式 .xls.xlsx  
  8.    logger.info(ext);  
  9.   
  10.     // 得到上传的文件  
  11.    MultipartFile fileFile = request.getFile("excelFile");  
  12.    try {  
  13.       // 转换成输入流  
  14.       InputStream in = fileFile.getInputStream();  
  15.       // 单元格  
  16.       Cell cell;  
  17.       List<Row> rsRows = new ExcelUtils().readExcel(ext, in);  
  18.       // 实例化对象  
  19.       SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");  
  20.       Map<Integer, String> map = new HashMap<Integer, String>();  
  21.       List<UserInfoVo> list = new LinkedList<UserInfoVo>();  
  22.   
  23.       if (rsRows.size() > 0 && rsRows != null) {  
  24.          for (int i = 1; i < rsRows.size(); i++) {  
  25.             for (int j = 0; j < rsRows.get(i).getLastCellNum(); j++) {  
  26.                cell = rsRows.get(i).getCell(j);  
  27.                map.put(j, new ExcelUtils().getCellValue(cell));  
  28.             }  
  29.             UserInfoVo userInfoVo = new UserInfoVo();  
  30.             userInfoVo.setNickName(map.get(1));  
  31.             userInfoVo.setGender(map.get(2).equals("男") ? 0 : 1);  
  32.             userInfoVo.setBirthday(sdf.parse(map.get(3)).getTime());  
  33.             userInfoVo.setRegisterDatetime(sdf.parse(map.get(4))  
  34.                   .getTime());  
  35.             userInfoVo.setState(1);  
  36.             list.add(userInfoVo);  
  37.          }  
  38.       }  
  39. }  

 

    List中即是excel表中的数据。这其中要用到一个工具类ExcelUtils。

Java代码 
  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.text.SimpleDateFormat;  
  7. import java.util.ArrayList;  
  8. import java.util.Date;  
  9. import java.util.List;  
  10.   
  11. import org.apache.poi.hssf.usermodel.HSSFDateUtil;  
  12. import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
  13. import org.apache.poi.ss.usermodel.Cell;  
  14. import org.apache.poi.ss.usermodel.CellStyle;  
  15. import org.apache.poi.ss.usermodel.Row;  
  16. import org.apache.poi.ss.usermodel.Sheet;  
  17. import org.apache.poi.ss.usermodel.Workbook;  
  18. import org.apache.poi.ss.util.CellRangeAddress;  
  19. import org.apache.poi.xssf.usermodel.XSSFWorkbook;  
  20.   
  21. public class ExcelUtils {  
  22.   
  23.    // %%%%%%%%-------常量部分 开始----------%%%%%%%%%  
  24.    /** 
  25.     * 默认的开始读取的行位置为第一行(索引值为0) 
  26.     */  
  27.    private final static int READ_START_POS = 0;  
  28.   
  29.    /** 
  30.     * 默认结束读取的行位置为最后一行(索引值=0,用负数来表示倒数第n行) 
  31.     */  
  32.    private final static int READ_END_POS = 0;  
  33.   
  34.    /** 
  35.     * 默认Excel内容的开始比较列位置为第一列(索引值为0) 
  36.     */  
  37.    private final static int COMPARE_POS = 0;  
  38.   
  39.    /** 
  40.     * 默认多文件合并的时需要做内容比较(相同的内容不重复出现) 
  41.     */  
  42.    private final static boolean NEED_COMPARE = true;  
  43.   
  44.    /** 
  45.     * 默认多文件合并的新文件遇到名称重复时,进行覆盖 
  46.     */  
  47.    private final static boolean NEED_OVERWRITE = true;  
  48.   
  49.    /** 
  50.     * 默认只操作一个sheet 
  51.     */  
  52.    private final static boolean ONLY_ONE_SHEET = true;  
  53.   
  54.    /** 
  55.     * 默认读取第一个sheet中(只有当ONLY_ONE_SHEET = true时有效) 
  56.     */  
  57.    private final static int SELECTED_SHEET = 0;  
  58.   
  59.    /** 
  60.     * 默认从第一个sheet开始读取(索引值为0) 
  61.     */  
  62.    private final static int READ_START_SHEET = 0;  
  63.   
  64.    /** 
  65.     * 默认在最后一个sheet结束读取(索引值=0,用负数来表示倒数第n行) 
  66.     */  
  67.    private final static int READ_END_SHEET = 0;  
  68.   
  69.    /** 
  70.     * 默认打印各种信息 
  71.     */  
  72.    private final static boolean PRINT_MSG = true;  
  73.   
  74.    // %%%%%%%%-------常量部分 结束----------%%%%%%%%%  
  75.   
  76.    // %%%%%%%%-------字段部分 开始----------%%%%%%%%%  
  77.    /** 
  78.     * Excel文件路径 
  79.     */  
  80.    private String excelPath = "data.xlsx";  
  81.   
  82.    /** 
  83.     * 设定开始读取的位置,默认为0 
  84.     */  
  85.    private int startReadPos = READ_START_POS;  
  86.   
  87.    /** 
  88.     * 设定结束读取的位置,默认为0,用负数来表示倒数第n行 
  89.     */  
  90.    private int endReadPos = READ_END_POS;  
  91.   
  92.    /** 
  93.     * 设定开始比较的列位置,默认为0 
  94.     */  
  95.    private int comparePos = COMPARE_POS;  
  96.   
  97.    /** 
  98.     * 设定汇总的文件是否需要替换,默认为true 
  99.     */  
  100.    private boolean isOverWrite = NEED_OVERWRITE;  
  101.   
  102.    /** 
  103.     * 设定是否需要比较,默认为true(仅当不覆写目标内容是有效,即isOverWrite=false时有效) 
  104.     */  
  105.    private boolean isNeedCompare = NEED_COMPARE;  
  106.   
  107.    /** 
  108.     * 设定是否只操作第一个sheet 
  109.     */  
  110.    private boolean onlyReadOneSheet = ONLY_ONE_SHEET;  
  111.   
  112.    /** 
  113.     * 设定操作的sheet在索引值 
  114.     */  
  115.    private int selectedSheetIdx = SELECTED_SHEET;  
  116.   
  117.    /** 
  118.     * 设定操作的sheet的名称 
  119.     */  
  120.    private String selectedSheetName = "";  
  121.   
  122.    /** 
  123.     * 设定开始读取的sheet,默认为0 
  124.     */  
  125.    private int startSheetIdx = READ_START_SHEET;  
  126.   
  127.    /** 
  128.     * 设定结束读取的sheet,默认为0,用负数来表示倒数第n行 
  129.     */  
  130.    private int endSheetIdx = READ_END_SHEET;  
  131.   
  132.    /** 
  133.     * 设定是否打印消息 
  134.     */  
  135.    private boolean printMsg = PRINT_MSG;  
  136.   
  137.    // %%%%%%%%-------字段部分 结束----------%%%%%%%%%  
  138.   
  139.    public ExcelUtils() {  
  140.   
  141.    }  
  142.   
  143.    public ExcelUtils(String excelPath) {  
  144.       this.excelPath = excelPath;  
  145.    }  
  146.   
  147.    /** 
  148.     * 还原设定(其实是重新new一个新的对象并返回) 
  149.     *  
  150.     * @return 
  151.     */  
  152.    public ExcelUtils RestoreSettings() {  
  153.       ExcelUtils instance = new ExcelUtils(this.excelPath);  
  154.       return instance;  
  155.    }  
  156.   
  157.    /** 
  158.     * 自动根据文件扩展名,调用对应的读取方法 
  159.     *  
  160.     * @Title: writeExcel 
  161.     * @Date : 2014-9-11 下午01:50:38 
  162.     * @throws IOException 
  163.     */  
  164.    public List<Row> readExcel() throws IOException {  
  165.       return readExcel(this.excelPath);  
  166.    }  
  167.   
  168.    /** 
  169.     * 自动根据文件扩展名,调用对应的读取方法 
  170.     *  
  171.     * @Title: writeExcel 
  172.     * @Date : 2014-9-11 下午01:50:38 
  173.     * @param xlsPath 
  174.     * @throws IOException 
  175.     */  
  176.    public List<Row> readExcel(String xlsPath) throws IOException {  
  177.   
  178.       // 扩展名为空时,  
  179.       if (xlsPath.equals("")) {  
  180.          throw new IOException("文件路径不能为空!");  
  181.       } else {  
  182.          File file = new File(xlsPath);  
  183.          if (!file.exists()) {  
  184.             throw new IOException("文件不存在!");  
  185.          }  
  186.       }  
  187.   
  188.       // 获取扩展名  
  189.       String ext = xlsPath.substring(xlsPath.lastIndexOf(".") + 1);  
  190.   
  191.       try {  
  192.   
  193.          if ("xls".equals(ext)) { // 使用xls方式读取  
  194.             return readExcel_xls(xlsPath);  
  195.          } else if ("xlsx".equals(ext)) { // 使用xlsx方式读取  
  196.             return readExcel_xlsx(xlsPath);  
  197.          } else { // 依次尝试xls、xlsx方式读取  
  198.             out("您要操作的文件没有扩展名,正在尝试以xls方式读取...");  
  199.             try {  
  200.                return readExcel_xls(xlsPath);  
  201.             } catch (IOException e1) {  
  202.                out("尝试以xls方式读取,结果失败!,正在尝试以xlsx方式读取...");  
  203.                try {  
  204.                   return readExcel_xlsx(xlsPath);  
  205.                } catch (IOException e2) {  
  206.                   out("尝试以xls方式读取,结果失败!n请您确保您的文件是Excel文件,并且无损,然后再试。");  
  207.                   throw e2;  
  208.                }  
  209.             }  
  210.          }  
  211.       } catch (IOException e) {  
  212.          throw e;  
  213.       }  
  214.    }  
  215.   
  216.    /** 
  217.     * 通过判断文件的扩展名,以不同的方式读取文件 
  218.     *  
  219.     * @author wufei 2016年9月19日 上午10:41:27 
  220.     * @Method: readExcel 
  221.     * @Description: TODO 
  222.     * @param @param ext 
  223.     * @param @param in 
  224.     * @param @return 
  225.     * @param @throws IOException 
  226.     * @return List<Row> 
  227.     * @throws 
  228.     */  
  229.    public List<Row> readExcel(String ext, InputStream in) {  
  230.   
  231.       try {  
  232.          if (".xls".equals(ext)) { // 使用xls方式读取  
  233.             return readExcel_xlsAsStream(in);  
  234.          } else if (".xlsx".equals(ext)) { // 使用xlsx方式读取  
  235.             return readExcel_xlsxAsStream(in);  
  236.          } else { // 依次尝试xls、xlsx方式读取  
  237.             out("您要操作的文件没有扩展名,正在尝试以xlsx方式读取...");  
  238.             try {  
  239.                return readExcel_xlsxAsStream(in);  
  240.             } catch (Exception e1) {  
  241.                out("尝试以xlsx方式读取,结果失败!,正在尝试以xls方式读取...");  
  242.                try {  
  243.                   return readExcel_xlsAsStream(in);  
  244.                } catch (IOException e2) {  
  245.                   out("尝试以xls方式读取,结果失败!n请您确保您的文件是Excel文件,并且无损,然后再试。");  
  246.                   throw e2;  
  247.                }  
  248.             }  
  249.          }  
  250.       } catch (IOException e) {  
  251.          out(e.getMessage());  
  252.          return null;  
  253.       }  
  254.    }  
  255.   
  256.    /** 
  257.     * 自动根据文件扩展名,调用对应的写入方法 
  258.     *  
  259.     * @Title: writeExcel 
  260.     * @Date : 2014-9-11 下午01:50:38 
  261.     * @param rowList 
  262.     * @throws IOException 
  263.     */  
  264.    public void writeExcel(List<Row> rowList) throws IOException {  
  265.       writeExcel(rowList, excelPath);  
  266.    }  
  267.   
  268.    /** 
  269.     * 自动根据文件扩展名,调用对应的写入方法 
  270.     *  
  271.     * @Title: writeExcel 
  272.     * @Date : 2014-9-11 下午01:50:38 
  273.     * @param rowList 
  274.     * @param xlsPath 
  275.     * @throws IOException 
  276.     */  
  277.    public void writeExcel(List<Row> rowList, String xlsPath)  
  278.          throws IOException {  
  279.   
  280.       // 扩展名为空时,  
  281.       if (xlsPath.equals("")) {  
  282.          throw new IOException("文件路径不能为空!");  
  283.       }  
  284.   
  285.       // 获取扩展名  
  286.       String ext = xlsPath.substring(xlsPath.lastIndexOf(".") + 1);  
  287.   
  288.       try {  
  289.   
  290.          if ("xls".equals(ext)) { // 使用xls方式写入  
  291.             writeExcel_xls(rowList, xlsPath);  
  292.          } else if ("xlsx".equals(ext)) { // 使用xlsx方式写入  
  293.             writeExcel_xlsx(rowList, xlsPath);  
  294.          } else { // 依次尝试xls、xlsx方式写入  
  295.             out("您要操作的文件没有扩展名,正在尝试以xls方式写入...");  
  296.             try {  
  297.                writeExcel_xls(rowList, xlsPath);  
  298.             } catch (IOException e1) {  
  299.                out("尝试以xls方式写入,结果失败!,正在尝试以xlsx方式读取...");  
  300.                try {  
  301.                   writeExcel_xlsx(rowList, xlsPath);  
  302.                } catch (IOException e2) {  
  303.                   out("尝试以xls方式写入,结果失败!n请您确保您的文件是Excel文件,并且无损,然后再试。");  
  304.                   throw e2;  
  305.                }  
  306.             }  
  307.          }  
  308.       } catch (IOException e) {  
  309.          throw e;  
  310.       }  
  311.    }  
  312.   
  313.    /** 
  314.     * 修改Excel(97-03版,xls格式) 
  315.     *  
  316.     * @Title: writeExcel_xls 
  317.     * @Date : 2014-9-11 下午01:50:38 
  318.     * @param rowList 
  319.     * @param dist_xlsPath 
  320.     * @throws IOException 
  321.     */  
  322.    public void writeExcel_xls(List<Row> rowList, String dist_xlsPath)  
  323.          throws IOException {  
  324.       writeExcel_xls(rowList, excelPath, dist_xlsPath);  
  325.    }  
  326.   
  327.    /** 
  328.     * 修改Excel(97-03版,xls格式) 
  329.     *  
  330.     * @Title: writeExcel_xls 
  331.     * @Date : 2014-9-11 下午01:50:38 
  332.     * @param rowList 
  333.     * @param src_xlsPath 
  334.     * @param dist_xlsPath 
  335.     * @throws IOException 
  336.     */  
  337.    public void writeExcel_xls(List<Row> rowList, String src_xlsPath,  
  338.          String dist_xlsPath) throws IOException {  
  339.   
  340.       // 判断文件路径是否为空  
  341.       if (dist_xlsPath == null || dist_xlsPath.equals("")) {  
  342.          out("文件路径不能为空");  
  343.          throw new IOException("文件路径不能为空");  
  344.       }  
  345.       // 判断文件路径是否为空  
  346.       if (src_xlsPath == null || src_xlsPath.equals("")) {  
  347.          out("文件路径不能为空");  
  348.          throw new IOException("文件路径不能为空");  
  349.       }  
  350.   
  351.       // 判断列表是否有数据,如果没有数据,则返回  
  352.       if (rowList == null || rowList.size() == 0) {  
  353.          out("文档为空");  
  354.          return;  
  355.       }  
  356.   
  357.       try {  
  358.          HSSFWorkbook wb = null;  
  359.   
  360.          // 判断文件是否存在  
  361.          File file = new File(dist_xlsPath);  
  362.          if (file.exists()) {  
  363.             // 如果复写,则删除后  
  364.             if (isOverWrite) {  
  365.                file.delete();  
  366.                // 如果文件不存在,则创建一个新的Excel  
  367.                // wb = new HSSFWorkbook();  
  368.                // wb.createSheet("Sheet1");  
  369.                wb = new HSSFWorkbook(new FileInputStream(src_xlsPath));  
  370.             } else {  
  371.                // 如果文件存在,则读取Excel  
  372.                wb = new HSSFWorkbook(new FileInputStream(file));  
  373.             }  
  374.          } else {  
  375.             // 如果文件不存在,则创建一个新的Excel  
  376.             // wb = new HSSFWorkbook();  
  377.             // wb.createSheet("Sheet1");  
  378.             wb = new HSSFWorkbook(new FileInputStream(src_xlsPath));  
  379.          }  
  380.   
  381.          // 将rowlist的内容写到Excel中  
  382.          writeExcel(wb, rowList, dist_xlsPath);  
  383.   
  384.       } catch (IOException e) {  
  385.          e.printStackTrace();  
  386.       }  
  387.    }  
  388.   
  389.    /** 
  390.     * 修改Excel(97-03版,xls格式) 
  391.     *  
  392.     * @Title: writeExcel_xls 
  393.     * @Date : 2014-9-11 下午01:50:38 
  394.     * @param rowList 
  395.     * @param dist_xlsPath 
  396.     * @throws IOException 
  397.     */  
  398.    public void writeExcel_xlsx(List<Row> rowList, String dist_xlsPath)  
  399.          throws IOException {  
  400.       writeExcel_xls(rowList, excelPath, dist_xlsPath);  
  401.    }  
  402.   
  403.    /** 
  404.     * 修改Excel(2007版,xlsx格式) 
  405.     *  
  406.     * @Title: writeExcel_xlsx 
  407.     * @Date : 2014-9-11 下午01:50:38 
  408.     * @param rowList 
  409.     * @throws IOException 
  410.     */  
  411.    public void writeExcel_xlsx(List<Row> rowList, String src_xlsPath,  
  412.          String dist_xlsPath) throws IOException {  
  413.   
  414.       // 判断文件路径是否为空  
  415.       if (dist_xlsPath == null || dist_xlsPath.equals("")) {  
  416.          out("文件路径不能为空");  
  417.          throw new IOException("文件路径不能为空");  
  418.       }  
  419.       // 判断文件路径是否为空  
  420.       if (src_xlsPath == null || src_xlsPath.equals("")) {  
  421.          out("文件路径不能为空");  
  422.          throw new IOException("文件路径不能为空");  
  423.       }  
  424.   
  425.       // 判断列表是否有数据,如果没有数据,则返回  
  426.       if (rowList == null || rowList.size() == 0) {  
  427.          out("文档为空");  
  428.          return;  
  429.       }  
  430.   
  431.       try {  
  432.          // 读取文档  
  433.          HSSFWorkbook wb = null;  
  434.   
  435.          // 判断文件是否存在  
  436.          File file = new File(dist_xlsPath);  
  437.          if (file.exists()) {  
  438.             // 如果复写,则删除后  
  439.             if (isOverWrite) {  
  440.                file.delete();  
  441.                // 如果文件不存在,则创建一个新的Excel  
  442.                // wb = new XSSFWorkbook();  
  443.                // wb.createSheet("Sheet1");  
  444.                wb = new HSSFWorkbook(new FileInputStream(src_xlsPath));  
  445.             } else {  
  446.                // 如果文件存在,则读取Excel  
  447.                wb = new HSSFWorkbook(new FileInputStream(file));  
  448.             }  
  449.          } else {  
  450.             // 如果文件不存在,则创建一个新的Excel  
  451.             // wb = new XSSFWorkbook();  
  452.             // wb.createSheet("Sheet1");  
  453.             wb = new HSSFWorkbook(new FileInputStream(src_xlsPath));  
  454.          }  
  455.          // 将rowlist的内容添加到Excel中  
  456.          writeExcel(wb, rowList, dist_xlsPath);  
  457.   
  458.       } catch (IOException e) {  
  459.          e.printStackTrace();  
  460.       }  
  461.    }  
  462.   
  463.    /** 
  464.     * //读取Excel 2007版,xlsx格式 
  465.     *  
  466.     * @Title: readExcel_xlsx 
  467.     * @Date : 2014-9-11 上午11:43:11 
  468.     * @return 
  469.     * @throws IOException 
  470.     */  
  471.    public List<Row> readExcel_xlsx() throws IOException {  
  472.       return readExcel_xlsx(excelPath);  
  473.    }  
  474.   
  475.    /** 
  476.     * //读取Excel 2007版,xlsx格式 
  477.     *  
  478.     * @Title: readExcel_xlsx 
  479.     * @Date : 2014-9-11 上午11:43:11 
  480.     * @return 
  481.     * @throws Exception 
  482.     */  
  483.    public List<Row> readExcel_xlsx(String xlsPath) throws IOException {  
  484.       // 判断文件是否存在  
  485.       File file = new File(xlsPath);  
  486.       if (!file.exists()) {  
  487.          throw new IOException("文件名为" + file.getName() + "Excel文件不存在!");  
  488.       }  
  489.   
  490.       XSSFWorkbook wb = null;  
  491.       List<Row> rowList = new ArrayList<Row>();  
  492.       try {  
  493.          FileInputStream fis = new FileInputStream(file);  
  494.          // 去读Excel  
  495.          wb = new XSSFWorkbook(fis);  
  496.   
  497.          // 读取Excel 2007版,xlsx格式  
  498.          rowList = readExcel(wb);  
  499.   
  500.       } catch (IOException e) {  
  501.          e.printStackTrace();  
  502.       }  
  503.       return rowList;  
  504.    }  
  505.   
  506.    /** 
  507.     * 以流的形式读取excel文件 2007版xlsx 
  508.     *  
  509.     * @author wufei 2016年9月19日 上午10:35:40 
  510.     * @Method: readExcel_xlsxAsStream 
  511.     * @Description: TODO 
  512.     * @param @param in 
  513.     * @param @return 
  514.     * @param @throws IOException 
  515.     * @return List<Row> 
  516.     * @throws 
  517.     */  
  518.    public List<Row> readExcel_xlsxAsStream(InputStream in) throws IOException {  
  519.   
  520.       XSSFWorkbook wb = null;  
  521.       List<Row> rowList = new ArrayList<Row>();  
  522.       try {  
  523.          // 去读Excel  
  524.          wb = new XSSFWorkbook(in);  
  525.   
  526.          // 读取Excel 2007版,xlsx格式  
  527.          rowList = readExcel(wb);  
  528.   
  529.       } catch (IOException e) {  
  530.          e.printStackTrace();  
  531.       }  
  532.       return rowList;  
  533.    }  
  534.   
  535.    /*** 
  536.     * 读取Excel(97-03版,xls格式) 
  537.     *  
  538.     * @throws IOException 
  539.     *  
  540.     * @Title: readExcel 
  541.     * @Date : 2014-9-11 上午09:53:21 
  542.     */  
  543.    public List<Row> readExcel_xls() throws IOException {  
  544.       return readExcel_xls(excelPath);  
  545.    }  
  546.   
  547.    /*** 
  548.     * 读取Excel(97-03版,xls格式) 
  549.     *  
  550.     * @throws Exception 
  551.     *  
  552.     * @Title: readExcel 
  553.     * @Date : 2014-9-11 上午09:53:21 
  554.     */  
  555.    public List<Row> readExcel_xls(String xlsPath) throws IOException {  
  556.   
  557.       // 判断文件是否存在  
  558.       File file = new File(xlsPath);  
  559.       if (!file.exists()) {  
  560.          throw new IOException("文件名为" + file.getName() + "Excel文件不存在!");  
  561.       }  
  562.   
  563.       HSSFWorkbook wb = null;// 用于Workbook级的操作,创建、删除Excel  
  564.       List<Row> rowList = new ArrayList<Row>();  
  565.   
  566.       try {  
  567.          // 读取Excel  
  568.          wb = new HSSFWorkbook(new FileInputStream(file));  
  569.   
  570.          // 读取Excel 97-03版,xls格式  
  571.          rowList = readExcel(wb);  
  572.   
  573.       } catch (IOException e) {  
  574.          e.printStackTrace();  
  575.       }  
  576.       return rowList;  
  577.    }  
  578.   
  579.    /** 
  580.     * 以流的形式读取97-03版excel文件 
  581.     *  
  582.     * @author wufei 2016年9月19日 上午10:33:25 
  583.     * @Method: readExcel_xlsAsStream 
  584.     * @Description: TODO 
  585.     * @param @param in 
  586.     * @param @return 
  587.     * @param @throws IOException 
  588.     * @return List<Row> 
  589.     * @throws 
  590.     */  
  591.    public List<Row> readExcel_xlsAsStream(InputStream in) throws IOException {  
  592.   
  593.       HSSFWorkbook wb = null;// 用于Workbook级的操作,创建、删除Excel  
  594.       List<Row> rowList = new ArrayList<Row>();  
  595.   
  596.       try {  
  597.          // 读取Excel  
  598.          wb = new HSSFWorkbook(in);  
  599.   
  600.          // 读取Excel 97-03版,xls格式  
  601.          rowList = readExcel(wb);  
  602.   
  603.       } catch (IOException e) {  
  604.          e.printStackTrace();  
  605.       }  
  606.       return rowList;  
  607.    }  
  608.   
  609.    /*** 
  610.     * 读取单元格的值 
  611.     *  
  612.     * @Title: getCellValue 
  613.     * @Date : 2014-9-11 上午10:52:07 
  614.     * @param cell 
  615.     * @return 
  616.     */  
  617.    public String getCellValue(Cell cell) {  
  618.       Object result = "";  
  619.       if (cell != null) {  
  620.          switch (cell.getCellType()) {  
  621.          case Cell.CELL_TYPE_STRING:  
  622.             result = cell.getStringCellValue();  
  623.             break;  
  624.          case Cell.CELL_TYPE_NUMERIC:  
  625.             // 判断是否为日期  
  626.             if (HSSFDateUtil.isCellDateFormatted(cell)) {  
  627.                SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");  
  628.                Date date = HSSFDateUtil.getJavaDate(cell  
  629.                      .getNumericCellValue());  
  630.                result = df.format(date);  
  631.             } else {  
  632.                result = cell.getNumericCellValue();  
  633.             }  
  634.             break;  
  635.          case Cell.CELL_TYPE_BOOLEAN:  
  636.             result = cell.getBooleanCellValue();  
  637.             break;  
  638.          case Cell.CELL_TYPE_FORMULA:  
  639.             result = cell.getCellFormula();  
  640.             break;  
  641.          case Cell.CELL_TYPE_ERROR:  
  642.             result = cell.getErrorCellValue();  
  643.             break;  
  644.          case Cell.CELL_TYPE_BLANK:  
  645.             break;  
  646.          default:  
  647.             break;  
  648.          }  
  649.       }  
  650.       return result.toString();  
  651.    }  
  652.   
  653.    /** 
  654.     * 通用读取Excel 
  655.     *  
  656.     * @Title: readExcel 
  657.     * @Date : 2014-9-11 上午11:26:53 
  658.     * @param wb 
  659.     * @return 
  660.     */  
  661.    private List<Row> readExcel(Workbook wb) {  
  662.       List<Row> rowList = new ArrayList<Row>();  
  663.   
  664.       int sheetCount = 1;// 需要操作的sheet数量  
  665.   
  666.       Sheet sheet = null;  
  667.       if (onlyReadOneSheet) { // 只操作一个sheet  
  668.          // 获取设定操作的sheet(如果设定了名称,按名称查,否则按索引值查)  
  669.          sheet = selectedSheetName.equals("") ? wb  
  670.                .getSheetAt(selectedSheetIdx) : wb  
  671.                .getSheet(selectedSheetName);  
  672.       } else { // 操作多个sheet  
  673.          sheetCount = wb.getNumberOfSheets();// 获取可以操作的总数量  
  674.       }  
  675.   
  676.       // 获取sheet数目  
  677.       for (int t = startSheetIdx; t < sheetCount + endSheetIdx; t++) {  
  678.          // 获取设定操作的sheet  
  679.          if (!onlyReadOneSheet) {  
  680.             sheet = wb.getSheetAt(t);  
  681.          }  
  682.   
  683.          // 获取最后行号  
  684.          int lastRowNum = sheet.getLastRowNum();  
  685.   
  686.          if (lastRowNum > 0) { // 如果>0,表示有数据  
  687.             out("n开始读取名为【" + sheet.getSheetName() + "】的内容:");  
  688.          }  
  689.   
  690.          Row row = null;  
  691.          // 循环读取  
  692.          for (int i = startReadPos; i <= lastRowNum + endReadPos; i++) {  
  693.             row = sheet.getRow(i);  
  694.             if (row != null) {  
  695.                rowList.add(row);  
  696.                out("第" + (i + 1) + "行:"false);  
  697.                // 获取每一单元格的值  
  698.                for (int j = 0; j < row.getLastCellNum(); j++) {  
  699.                   String value = getCellValue(row.getCell(j));  
  700.                   if (!value.equals("")) {  
  701.                      out(value + " | "false);  
  702.                   }  
  703.                }  
  704.                out("");  
  705.             }  
  706.          }  
  707.       }  
  708.       return rowList;  
  709.    }  
  710.   
  711.    /** 
  712.     * 修改Excel,并另存为 
  713.     *  
  714.     * @Title: WriteExcel 
  715.     * @Date : 2014-9-11 下午01:33:59 
  716.     * @param wb 
  717.     * @param rowList 
  718.     * @param xlsPath 
  719.     */  
  720.    private void writeExcel(Workbook wb, List<Row> rowList, String xlsPath) {  
  721.   
  722.       if (wb == null) {  
  723.          out("操作文档不能为空!");  
  724.          return;  
  725.       }  
  726.   
  727.       Sheet sheet = wb.getSheetAt(0);// 修改第一个sheet中的值  
  728.   
  729.       // 如果每次重写,那么则从开始读取的位置写,否则果获取源文件最新的行。  
  730.       int lastRowNum = isOverWrite ? startReadPos : sheet.getLastRowNum() + 1;  
  731.       int t = 0;// 记录最新添加的行数  
  732.       out("要添加的数据总条数为:" + rowList.size());  
  733.       for (Row row : rowList) {  
  734.          if (row == null)  
  735.             continue;  
  736.          // 判断是否已经存在该数据  
  737.          int pos = findInExcel(sheet, row);  
  738.   
  739.          Row r = null;// 如果数据行已经存在,则获取后重写,否则自动创建新行。  
  740.          if (pos >= 0) {  
  741.             sheet.removeRow(sheet.getRow(pos));  
  742.             r = sheet.createRow(pos);  
  743.          } else {  
  744.             r = sheet.createRow(lastRowNum + t++);  
  745.          }  
  746.   
  747.          // 用于设定单元格样式  
  748.          CellStyle newstyle = wb.createCellStyle();  
  749.   
  750.          // 循环为新行创建单元格  
  751.          for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {  
  752.             Cell cell = r.createCell(i);// 获取数据类型  
  753.             cell.setCellValue(getCellValue(row.getCell(i)));// 复制单元格的值到新的单元格  
  754.             // cell.setCellStyle(row.getCell(i).getCellStyle());//出错  
  755.             if (row.getCell(i) == null)  
  756.                continue;  
  757.             copyCellStyle(row.getCell(i).getCellStyle(), newstyle); // 获取原来的单元格样式  
  758.             cell.setCellStyle(newstyle);// 设置样式  
  759.             // sheet.autoSizeColumn(i);//自动跳转列宽度  
  760.          }  
  761.       }  
  762.       out("其中检测到重复条数为:" + (rowList.size() - t) + " ,追加条数为:" + t);  
  763.   
  764.       // 统一设定合并单元格  
  765.       setMergedRegion(sheet);  
  766.   
  767.       try {  
  768.          // 重新将数据写入Excel中  
  769.          FileOutputStream outputStream = new FileOutputStream(xlsPath);  
  770.          wb.write(outputStream);  
  771.          outputStream.flush();  
  772.          outputStream.close();  
  773.       } catch (Exception e) {  
  774.          out("写入Excel时发生错误! ");  
  775.          e.printStackTrace();  
  776.       }  
  777.    }  
  778.   
  779.    /** 
  780.     * 查找某行数据是否在Excel表中存在,返回行数。 
  781.     *  
  782.     * @Title: findInExcel 
  783.     * @Date : 2014-9-11 下午02:23:12 
  784.     * @param sheet 
  785.     * @param row 
  786.     * @return 
  787.     */  
  788.    private int findInExcel(Sheet sheet, Row row) {  
  789.       int pos = -1;  
  790.   
  791.       try {  
  792.          // 如果覆写目标文件,或者不需要比较,则直接返回  
  793.          if (isOverWrite || !isNeedCompare) {  
  794.             return pos;  
  795.          }  
  796.          for (int i = startReadPos; i <= sheet.getLastRowNum() + endReadPos; i++) {  
  797.             Row r = sheet.getRow(i);  
  798.             if (r != null && row != null) {  
  799.                String v1 = getCellValue(r.getCell(comparePos));  
  800.                String v2 = getCellValue(row.getCell(comparePos));  
  801.                if (v1.equals(v2)) {  
  802.                   pos = i;  
  803.                   break;  
  804.                }  
  805.             }  
  806.          }  
  807.       } catch (Exception e) {  
  808.          e.printStackTrace();  
  809.       }  
  810.       return pos;  
  811.    }  
  812.   
  813.    /** 
  814.     * 复制一个单元格样式到目的单元格样式 
  815.     *  
  816.     * @param fromStyle 
  817.     * @param toStyle 
  818.     */  
  819.    public static void copyCellStyle(CellStyle fromStyle, CellStyle toStyle) {  
  820.       toStyle.setAlignment(fromStyle.getAlignment());  
  821.       // 边框和边框颜色  
  822.       toStyle.setBorderBottom(fromStyle.getBorderBottom());  
  823.       toStyle.setBorderLeft(fromStyle.getBorderLeft());  
  824.       toStyle.setBorderRight(fromStyle.getBorderRight());  
  825.       toStyle.setBorderTop(fromStyle.getBorderTop());  
  826.       toStyle.setTopBorderColor(fromStyle.getTopBorderColor());  
  827.       toStyle.setBottomBorderColor(fromStyle.getBottomBorderColor());  
  828.       toStyle.setRightBorderColor(fromStyle.getRightBorderColor());  
  829.       toStyle.setLeftBorderColor(fromStyle.getLeftBorderColor());  
  830.   
  831.       // 背景和前景  
  832.       toStyle.setFillBackgroundColor(fromStyle.getFillBackgroundColor());  
  833.       toStyle.setFillForegroundColor(fromStyle.getFillForegroundColor());  
  834.   
  835.       // 数据格式  
  836.       toStyle.setDataFormat(fromStyle.getDataFormat());  
  837.       toStyle.setFillPattern(fromStyle.getFillPattern());  
  838.       // toStyle.setFont(fromStyle.getFont(null));  
  839.       toStyle.setHidden(fromStyle.getHidden());  
  840.       toStyle.setIndention(fromStyle.getIndention());// 首行缩进  
  841.       toStyle.setLocked(fromStyle.getLocked());  
  842.       toStyle.setRotation(fromStyle.getRotation());// 旋转  
  843.       toStyle.setVerticalAlignment(fromStyle.getVerticalAlignment());  
  844.       toStyle.setWrapText(fromStyle.getWrapText());  
  845.   
  846.    }  
  847.   
  848.    /** 
  849.     * 获取合并单元格的值 
  850.     *  
  851.     * @param sheet 
  852.     * @return 
  853.     */  
  854.    public void setMergedRegion(Sheet sheet) {  
  855.       int sheetMergeCount = sheet.getNumMergedRegions();  
  856.   
  857.       for (int i = 0; i < sheetMergeCount; i++) {  
  858.          // 获取合并单元格位置  
  859.          CellRangeAddress ca = sheet.getMergedRegion(i);  
  860.          int firstRow = ca.getFirstRow();  
  861.          if (startReadPos - 1 > firstRow) {// 如果第一个合并单元格格式在正式数据的上面,则跳过。  
  862.             continue;  
  863.          }  
  864.          int lastRow = ca.getLastRow();  
  865.          int mergeRows = lastRow - firstRow;// 合并的行数  
  866.          int firstColumn = ca.getFirstColumn();  
  867.          int lastColumn = ca.getLastColumn();  
  868.          // 根据合并的单元格位置和大小,调整所有的数据行格式,  
  869.          for (int j = lastRow + 1; j <= sheet.getLastRowNum(); j++) {  
  870.             // 设定合并单元格  
  871.             sheet.addMergedRegion(new CellRangeAddress(j, j + mergeRows,  
  872.                   firstColumn, lastColumn));  
  873.             j = j + mergeRows;// 跳过已合并的行  
  874.          }  
  875.   
  876.       }  
  877.    }  
  878.   
  879.    /** 
  880.     * 打印消息, 
  881.     *  
  882.     * @param msg 
  883.     *            消息内容 换行 
  884.     */  
  885.    private void out(String msg) {  
  886.       if (printMsg) {  
  887.          out(msg, true);  
  888.       }  
  889.    }  
  890.   
  891.    /** 
  892.     * 打印消息, 
  893.     *  
  894.     * @param msg 
  895.     *            消息内容 
  896.     * @param tr 
  897.     *            换行 
  898.     */  
  899.    private void out(String msg, boolean tr) {  
  900.       if (printMsg) {  
  901.          System.out.print(msg + (tr ? "n" : ""));  
  902.       }  
  903.    }  
  904.   
  905.    public String getExcelPath() {  
  906.       return this.excelPath;  
  907.    }  
  908.   
  909.    public void setExcelPath(String excelPath) {  
  910.       this.excelPath = excelPath;  
  911.    }  
  912.   
  913.    public boolean isNeedCompare() {  
  914.       return isNeedCompare;  
  915.    }  
  916.   
  917.    public void setNeedCompare(boolean isNeedCompare) {  
  918.       this.isNeedCompare = isNeedCompare;  
  919.    }  
  920.   
  921.    public int getComparePos() {  
  922.       return comparePos;  
  923.    }  
  924.   
  925.    public void setComparePos(int comparePos) {  
  926.       this.comparePos = comparePos;  
  927.    }  
  928.   
  929.    public int getStartReadPos() {  
  930.       return startReadPos;  
  931.    }  
  932.   
  933.    public void setStartReadPos(int startReadPos) {  
  934.       this.startReadPos = startReadPos;  
  935.    }  
  936.   
  937.    public int getEndReadPos() {  
  938.       return endReadPos;  
  939.    }  
  940.   
  941.    public void setEndReadPos(int endReadPos) {  
  942.       this.endReadPos = endReadPos;  
  943.    }  
  944.   
  945.    public boolean isOverWrite() {  
  946.       return isOverWrite;  
  947.    }  
  948.   
  949.    public void setOverWrite(boolean isOverWrite) {  
  950.       this.isOverWrite = isOverWrite;  
  951.    }  
  952.   
  953.    public boolean isOnlyReadOneSheet() {  
  954.       return onlyReadOneSheet;  
  955.    }  
  956.   
  957.    public void setOnlyReadOneSheet(boolean onlyReadOneSheet) {  
  958.       this.onlyReadOneSheet = onlyReadOneSheet;  
  959.    }  
  960.   
  961.    public int getSelectedSheetIdx() {  
  962.       return selectedSheetIdx;  
  963.    }  
  964.   
  965.    public void setSelectedSheetIdx(int selectedSheetIdx) {  
  966.       this.selectedSheetIdx = selectedSheetIdx;  
  967.    }  
  968.   
  969.    public String getSelectedSheetName() {  
  970.       return selectedSheetName;  
  971.    }  
  972.   
  973.    public void setSelectedSheetName(String selectedSheetName) {  
  974.       this.selectedSheetName = selectedSheetName;  
  975.    }  
  976.   
  977.    public int getStartSheetIdx() {  
  978.       return startSheetIdx;  
  979.    }  
  980.   
  981.    public void setStartSheetIdx(int startSheetIdx) {  
  982.       this.startSheetIdx = startSheetIdx;  
  983.    }  
  984.   
  985.    public int getEndSheetIdx() {  
  986.       return endSheetIdx;  
  987.    }  
  988.   
  989.    public void setEndSheetIdx(int endSheetIdx) {  
  990.       this.endSheetIdx = endSheetIdx;  
  991.    }  
  992.   
  993.    public boolean isPrintMsg() {  
  994.       return printMsg;  
  995.    }  
  996.   
  997.    public void setPrintMsg(boolean printMsg) {  
  998.       this.printMsg = printMsg;  
  999.    }  
  1000. }  

    至此,读取完毕。

最后

以上就是任性星星为你收集整理的Java读取Excel文件汇总的全部内容,希望文章能够帮你解决Java读取Excel文件汇总所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部