【主机分销系统源码】【潮州溯源码燕窝】【红包扫雷源码屋】hssfworkbook源码

时间:2024-12-23 23:11:23 编辑:二板龙头公式源码 来源:卡盟搭建源码

1.java通过poi把excel文件导入mysql数据库报错
2.Your stream was neither an OLE2 stream,源码 nor an OOXML stream
3.HSSF XSSF SXSSF
4.如何用Apache POI读取Excel

hssfworkbook源码

java通过poi把excel文件导入mysql数据库报错

       java通过poi把excel文件导入mysql数据库报错是因为excel中的数据类型要跟mysql中的数据类型和长度对应,否则类型转换异常是源码主机分销系统源码最常见的。所以插入到mysql数据库的源码潮州溯源码燕窝时候需要做类型检查。

       1、源码红包扫雷源码屋Excel中的源码软件下载库源码测试数据:

       2、数据库表结构:

       CREATE TABLE `student_info` (

         `id` int() NOT NULL AUTO_INCREMENT,源码主力胜负筹码源码

         `no` varchar() DEFAULT NULL,

         `name` varchar() DEFAULT NULL,

         `age` varchar() DEFAULT NULL,

         `score` float DEFAULT '0',

         PRIMARY KEY (`id`)

       ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

       3、java源码部分ReadExcel.java:

       /

**

        * 读取excel中的源码数据并插入db

        */

       import java.io.FileInputStream;

       import java.io.IOException;

       import java.io.InputStream;

       import java.util.ArrayList;

       import java.util.List;

       import org.apache.poi.hssf.usermodel.HSSFCell;

       import org.apache.poi.hssf.usermodel.HSSFRow;

       import org.apache.poi.hssf.usermodel.HSSFSheet;

       import org.apache.poi.hssf.usermodel.HSSFWorkbook;

       import com.b.common.Common;

       import com.b.excel.vo.Student;

       /

**

        * @author pieryon

        * @created -5-

        */

       public class ReadExcel {

           public List<Student> readXls() throws IOException {

               InputStream is = new FileInputStream(Common.EXCEL_PATH);

               HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);

               Student student = null;

               List<Student> list = new ArrayList<Student>();

               // 循环工作表Sheet

               for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {

                   HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);

                   if (hssfSheet == null) {

                       continue;

                   }

                   // 循环行Row

                   for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {

                       HSSFRow hssfRow = hssfSheet.getRow(rowNum);

                       if (hssfRow != null) {

                           student = new Student();

                           HSSFCell no = hssfRow.getCell(0);

                           HSSFCell name = hssfRow.getCell(1);

                           HSSFCell age = hssfRow.getCell(2);

                           HSSFCell score = hssfRow.getCell(3);

                           student.setNo(getValue(no));

                           student.setName(getValue(name));

                           student.setAge(getValue(age));

                           student.setScore(Float.valueOf(getValue(score)));

                           list.add(student);

                       }

                   }

               }

               return list;

           }

           

            @SuppressWarnings("static-access")

           private String getValue(HSSFCell hssfCell) {

                   if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {

                       // 返回布尔类型的值

                       return String.valueOf(hssfCell.getBooleanCellValue());

                   } else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {

                       // 返回数值类型的值

                       return String.valueOf(hssfCell.getNumericCellValue());

                   } else {

                       // 返回字符串类型的值

                       return String.valueOf(hssfCell.getStringCellValue());

                   }

               }

       }

       2、SaveData2DB.java

       /

**

        * 插入数据到db

        */

       import java.io.IOException;

       import java.sql.SQLException;

       import java.util.List;

       import com.b.common.Common;

       import com.b.excel.util.DbUtil;

       import com.b.excel.vo.Student;

       /

**

        * @author pieryon

        * @created -5-

        */

       public class SaveData2DB {

           @SuppressWarnings({ "rawtypes" })

           public void save() throws IOException,源码 SQLException {

               ReadExcel xlsMain = new ReadExcel();

               Student student = null;

               List<Student> list = xlsMain.readXls();

               for (int i = 0; i < list.size(); i++) {

                   student = list.get(i);

                   List l = DbUtil.selectOne(Common.SELECT_STUDENT_SQL + "'%" + student.getName() + "%'", student);

                   if (!l.contains(1)) {

                       DbUtil.insert(Common.INSERT_STUDENT_SQL, student);

                   } else {

                       System.out.println("The Record was Exist : No. = " + student.getNo() + " , Name = " + student.getName() + ", Age = " + student.getAge() + ", and has been throw away!");

                   }

               }

           }

       }

       保存结果:

Your stream was neither an OLE2 stream, nor an OOXML stream

        最近使用Apache poi 做excel导出的功能,遇到了如下问题:

        起初对比其他的web工程,没有发现如何解决。最后找到抛出此异常的源码:

        org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:)

        可以看到,在调用 WorkbookFactory.create(inputStream) 来创建Workbook时,会根据文件类型(文件头)来区别、创建合适的Workbook对象。如果不满足前两个if条件里的 hasPOIFSHeader() 方法,就会抛出异常。而两个if里的hasPOIFSHeader()方法就是针对Excel和Excel的判断,读取文件流中的文件头(byte[8])信息去判断。

        那既然是根据文件的头部信息去比对进行判断的,并且excel只有和两个版本,那为什么放在classpath下的excel模板读取后创建WorkBook时,文件header判断都不符合呢?

        最后找到原因:maven编译打包时,将resources下的资源文件转码了。最终web工程打出的jar/war包,里面归档进去的excel模板文件都是乱码,文件头信息被修改,导致poi根本无法识别这样的excel文件。

        项目的pom.xml中添加maven资源插件

        1、推荐使用poi-ooxml中的 WorkbookFactory.create(inputStream) 来创建Workbook,因为HSSFWorkbook和XSSFWorkbook都实现了Workbook接口。(Excel和Excel两个版本在此通过文件header进行适配)

        2、当你的工程中,需要放入一些静态资源文件作为模板,比如excel填充模板,word模板(里面有些固定样式,程序运行时用模板导出报表类的),这个时候,最好都配置maven去除资源文件不被转码。下面的链接有2种方式。

        Maven 打包 过滤资源文件

        /qing_mei_xiu/article/details/

HSSF XSSF SXSSF

        1.创建工作簿Workbook

        2.创建Sheet

        3.创建行Row

        4.创建单元格Cell

        HSSFWorkbook是操作Excel以前(包括)的版本,扩展名为.xls,所以每个Sheet局限就是导出的行数至多为行,一般不会发生内存不足的情况(OOM)。

        这种形式的出现是由于HSSFWorkbook的局限性而产生的,因为其所导出的行数比较少,并且只针对Excel以前(包括)的版本的版本,所以 XSSFWookbook应运而生,其对应的是EXCEL以后的版本(行,列)扩展名.xlsx,每个Sheet最多可以导出万行,不过这样就伴随着一个OOM内存溢出的问题,原因是你所创建的sheet row cell 等此时是存在内存中的,随着数据量增大 ,内存的需求量也就增大,那么很大可能就是要OOM了。

        从POI 3.8版本开始,提供了一种基于XSSFWorkbook的低内存占用的工作簿SXSSFWorkbook。

        引用官方的介绍,简单概括就是:

        SXSSF是对XSSF的一种流式扩展,特点是采用了滑动窗口的机制,低内存占用,主要用于数据量非常大的电子表格而虚拟机堆有限的情况。

        原理是利用了滑动窗口机制。

        SXSSFWorkbook.DEFAULT_WINDOW_SIZE默认值是,表示在内存中最多存在个Row对象,当写第个Row对象的时候就会把第1个Row对象以XML格式写入C:\Users\wange\AppData\Local\Temp路径下的临时文件中,后面的以此类推,始终保持内存中最多存在个Row对象。

        SXSSFWorkbook默认使用内联字符串而不是 共享字符串表 (SharedStringsTable)。启用共享字符串时,文档中的所有唯一字符串都必须保存在内存中,因此会占用更多的内存。

        与XSSF的对比,在一个时间点上,只可以访问一定数量的Row;不再支持Sheet.clone();不再支持公式的求值。但是除了滑动窗口,其余的EXCLE操作仍然使用的是XSSF的API。

        另外官方提示导出EXCEL后应该调用wb.dispose()来删除之前保存的临时文件。

        wb.write(out)通过源码了解到过程是

        1、将wb的所有sheet调用flushRows()移出内存,写入临时.xml文件中

        2、生成了一个临时.xlsx文件将wb的一些模板数据写入这个临时文件

        3、将这个临时.xlsx文件转成ZipFile,遍历所有ZipEntry来获取Sheet,如果没有Sheet则直接复制流。

        4、如果能够获取到Sheet的则是那些临时.xml文件,在对这些文件进行解析并追踪写入导出文件中。

        (这边可能是涉及到了一些EXCEL文件格式的原理,就不深入研究了)

        SXSSFWorkbook wb = new SXSSFWorkbook(-1)

        初始化设置为-1的时候我们可以自己定义写临时文件规则,比如每读行记录flush到临时一次,可以大大减少磁盘IO次数。

        使用SAX模型来解析EXCEL不像DOM模型一下把所有文件内容加载进内存,它逐行扫描文档,一边扫描,一边解析。所以那些只需要单遍读取内容的应用程序就可以从SAX解析中受益,这对大型文档的解析是个巨大优势。

如何用Apache POI读取Excel

       ã€€ã€€é¦–å…ˆPOI是开源组织Apache出品的一个开源jar包,提供了方便解析Excel的API,我们可以非常方便的使用它来读取Excel。这里介绍3.5Final版本。

       ã€€ã€€æ‰€éœ€ç”¨åˆ°çš„jar包如下:

       ã€€ã€€è¯´åˆ°Excel,有和,格式是不一样的,用POI解析的方法也就不一样,Excel主要是使用org.apache.poi.hssf.usermodel包中的类来解析,而Excel就是使用org.apache.poi.xssf.usermodel来解析。

       ã€€ã€€è§£æžExcel源码

       è¯´åˆ°Excel,有和,格式是不一样的,用POI解析的方法也就不一样,Excel主要是使用org.apache.poi.hssf.usermodel包中的类来解析,而Excel就是使用org.apache.poi.xssf.usermodel来解析。

       è§£æžExcel源码

       StringBuffer content = new StringBuffer();

         HSSFWorkbook workbook = new HSSFWorkbook(is); // 创建对Excel工作簿文件的引用

         for (int numSheets = 0; numSheets < workbook.getNumberOfSheets(); numSheets++) {

          if (null != workbook.getSheetAt(numSheets)) {

           HSSFSheet aSheet = workbook.getSheetAt(numSheets); // 获得一个sheet

           for (int rowNumOfSheet = 0; rowNumOfSheet <= aSheet.getLastRowNum(); rowNumOfSheet++) {

            if (null != aSheet.getRow(rowNumOfSheet)) {

             HSSFRow aRow = aSheet.getRow(rowNumOfSheet); // 获得一行

             for (int cellNumOfRow = 0; cellNumOfRow <= aRow.getLastCellNum(); cellNumOfRow++) {

              if (null != aRow.getCell(cellNumOfRow)) {

               HSSFCell aCell = aRow.getCell(cellNumOfRow); // 获得列值

               

               if (aCell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {

                content.append(aCell.getNumericCellValue() + "\t");

               } else if (aCell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN) {

                content.append(aCell.getBooleanCellValue() + "\t");

               } else if (aCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {

                content.append(aCell.getStringCellValue() + "\t");

               } else if (aCell.getCellType() == HSSFCell.CELL_TYPE_FORMULA){

                content.append(aCell.getCellFormula() + "\t");

               } else {

                continue;

               }

              }

              if(cellNumOfRow == aRow.getLastCellNum()) {

               content.append("\n");

              }

             }

            }

           }

          }

         }

         return content.toString().trim();

        

       è§£æžExcel和基本一样,只是将HSSFSheet,HSSFCell等都改成XSSFSheet,XSSFCell即可。

       å¦å¤–要提醒大家的是Excel的样式都是基于一个单元格的,所以用HSSFRow.getRowStyle()拿样式会出问题的,不一定会拿到你想要的样式。处理合并单元格是POI的一个难点,只能通过判断当前单元格是否在合并单元格之中,如果是,那此单元格的值便是这个合并单元格的首位置单元格的值,只有通过这样才能来处理合并单元格。

       å¤„理合并单元格的代码:

        public static boolean isMergedRegion(HSSFSheet sheet, HSSFCell cell) {

         //得到一个sheet中有多少个合并单元格

         int sheetmergerCount = sheet.getNumMergedRegions();

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

          //得出具体的合并单元格

          CellRangeAddress ca = sheet.getMergedRegion(i);

          //得到合并单元格的起始行, 结束行, 起始列, 结束列

          int firstC = ca.getFirstColumn();

          int lastC = ca.getLastColumn();

          int firstR = ca.getFirstRow();

          int lastR = ca.getLastRow();

          //判断该单元格是否在合并单元格范围之内, 如果是, 则返回 true

          if(cell.getColumnIndex() <= lastC && cell.getColumnIndex() >= firstC) {

           if(cell.getRowIndex() <= lastR && cell.getRowIndex() >= firstR) {

            return true;

           }

          }

         }

         return false;

        }

        

        public static String getMergedRegionValue(HSSFSheet sheet, HSSFCell cell) {

         //获得一个 sheet 中合并单元格的数量

         int sheetmergerCount = sheet.getNumMergedRegions();

         //便利合并单元格

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

          //获得合并单元格

          CellRangeAddress ca = sheet.getMergedRegion(i);

          //获得合并单元格的起始行, 结束行, 起始列, 结束列

          int firstC = ca.getFirstColumn();

          int lastC = ca.getLastColumn();

          int firstR = ca.getFirstRow();

          int lastR = ca.getLastRow();

          //判断该单元格是否是在合并单元格中, 如果是, 则返回所在合并单元格的首单元格的值

          if(cell.getColumnIndex() <= lastC && cell.getColumnIndex() >= firstC) {

           if(cell.getRowIndex() <= lastR && cell.getRowIndex() >= firstR) {

            HSSFRow fRow = sheet.getRow(firstR);

            HSSFCell fCell = fRow.getCell(firstC);

            //除了合并单元格首单元格的值, 其余的用(*)来区分

            if (fCell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC && hasBorder(cell)) {

             return String.valueOf(fCell.getNumericCellValue());

            } else if (fCell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN && hasBorder(cell)) {

             return String.valueOf(fCell.getBooleanCellValue());

            } else if (fCell.getCellType() == HSSFCell.CELL_TYPE_STRING && hasBorder(cell)) {

             return fCell.getStringCellValue();

            } else if (fCell.getCellType() == HSSFCell.CELL_TYPE_FORMULA && hasBorder(cell)){

             return String.valueOf(fCell.getCellFormula());

            }

           }

          }

         }

         return "";

        }