xlsm中默认启动宏,而xlsx则是虽然带有宏,也不会被Excel执行。
1,POI-3.15的Sheet.getLastRowNum()是0-based;Row.getLastColNum()结果是1-based。
2,poi中getPhysicalNumberOfRows()和getLastRowNum()区别 : 举例说明:修改xlsx文件后缀为rar,解压之(xlsx是ooxml格式的文件)。找到xl/worksheets/sheet*.xml文件,打开,可以看到这是一个xml文件,这时候,如果我们在其中的sheetData元素中添加一个空的<row></row>
标签。 getPhysicalNumberOfRows()计算的是所有的<row>
标签的总数。 getLastRowNum()计算的是所有<row>
标签中r属性(行号)的最大值。 所以我们在遍历EXCEL的时候,应该使用的遍历行号上限(闭区间)是getLastRowNum().在这其中,可能会遇到Row==null的情况需要跳过。 另一方面,出于业务方向的考虑,我们一般要检查row!=null的时候一行中是否全是“空白”符号,如果全是空白符号的行一般不作为数据行分析。 3,有关格式,千万不要试图将那些线程不安全的对象作为静态常量,之前在使用jxl框架的时候,企图将格式对象作为全局静态常量,最后居然在因为线程不安全居然出现了相当摸不着头脑的bug(第一次导出成功,之后的同一导出请求的返回数据文件很可能会被损坏)。
辅助类:
/** * @author 80375068 * @version 1.0 * @date 2016/12/21 * @package demo */public class WorkbookFactory { /** * 读取excel输入流 * @param ips * @return */ public static Workbook createWorkBook(InputStream ips){ Workbook workbook=null; try{ workbook=getWorkBook(ips); }catch (Exception ex){ throw new AppInternalException("打开EXCEL文件流失败!",ex); } return workbook; } /** * 根据excel输入流创建WorkBook * @param ips * @return * @throws java.io.IOException */ PRivate static Workbook getWorkBook(InputStream ips) throws IOException { Workbook workbook=null; //输入流必须支持mark/reset方法 if(!ips.markSupported()){ ips=new PushbackInputStream(ips,8); } //使用微软Office文件系统,Excel2003 if(POIFSFileSystem.haspOIFSHeader(ips)){ workbook=new HSSFWorkbook(ips); }else if(DocumentFactoryHelper.hasOOXMLHeader(ips)){ workbook=new XSSFWorkbook(ips); } return workbook; }}基本的业务代码
Workbook workbook = WorkbookFactory.createWorkBook(is);Sheet sheet = workbook.getSheetAt(0);for(Row row:sheet){ for(Cell cell:row){ new DataFormatter().formatCellValue(cell); }}辅助类:
public class ExcelWriter implements Closeable{ private OutputStream ops; private Workbook workbook; public ExcelWriter(OutputStream ops, ExcelType excelType) { //使用缓冲输出流 this.ops = new BufferedOutputStream(ops, 8192); //创建xls或者xlsx if (excelType.XLS.equals(excelType)) { this.workbook = new HSSFWorkbook(); } else { this.workbook = new XSSFWorkbook(); } } /** * 将WorkBook写到输出流中 * * @throws java.io.IOException */ public void write() throws IOException { workbook.write(ops); ops.close(); ops = null; } public Workbook getWorkbook() { return workbook; } @Override public void close() { if (ops != null) { try { ops.close(); } catch (IOException ex) { //静默关闭 } } } public enum ExcelType { XLS("xls", "EXCEL_2003", false), XLSX("xlsx", "EXCEL_2007", false), XSLM("xlsm", "EXCEL_2007", true); //文件后缀名 private String suffix; //文件版本 private String vision; //是否启用宏 private boolean macros; private ExcelType(String suffix, String vision, boolean macros) { this.suffix = suffix; this.vision = vision; this.macros = macros; } public boolean hasMacros() { return macros; } public String getSuffix() { return suffix; } public String getVision() { return vision; } }}基本业务代码(用于Servlet中)
private ExcelWriter createExcel(HttpServletResponse response,String fileName) throws IOException { response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition","attachment;filename=" + new String(fileName.getBytes(AppGlobal.getMessageEncoding()), "ISO_8859_1")); response.setHeader("filename", URLEncoder.encode(fileName, AppGlobal.getMessageEncoding())); // 获取表头 List<ColumnOut> columns = module.getColumnsInfo(chosenCols); ExcelWriter writer=new ExcelWriter(response.getOutputStream(), ExcelWriter.ExcelType.XLS); Workbook wb = writer.getWorkbook(); Sheet sheet = wb.createSheet(); // 格式 CellStyle headStyle=wb.createCellStyle(); Font headFont=wb.createFont(); headFont.setFontName("ARIAL"); headFont.setFontHeightInPoints((short) 10); headFont.setBold(true); headStyle.setFont(headFont); headStyle.setAlignment(HorizontalAlignment.CENTER); //行 Row row=sheet.creatRow(0);//第0行 //单元格 A1 Cell cell=row.creatCell(0); cell.setStyle(headStyle);//格式 cell.setValue("abc");//value新闻热点
疑难解答