• java 使用 poi 操纵 excel2003 经验总结


    poi简介:

      Apache POIApache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能。 .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 POI 的功能。

    结构

    • HSSF - 提供读写Microsoft Excel XLS格式档案的功能。
    • XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。
    • HWPF - 提供读写Microsoft Word DOC格式档案的功能。
    • HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
    • HDGF - 提供读Microsoft Visio格式档案的功能。
    • HPBF - 提供读Microsoft Publisher格式档案的功能。
    • HSMF - 提供读Microsoft Outlook格式档案

    操纵excel2003的类大多在hssf包中。

    由于poi只提供了复制sheet的方法没有提供复制row的方法,在这里先贴出复制row的方法,以便今后查阅使用。

    复制行
     1 /** 
     2      * 复制行 ,在poi中excel的sheet,row,cell都从0开始
     3      *  
     4      * @param startRowIndex 
     5      *            起始行 
     6      * @param endRowIndex 
     7      *            结束行 
     8      * @param rowNum 
     9      *           移动行数,大于0为向下复制,小于0为向上复制
    10      */  
    11     private static void copyRows(HSSFSheet sheet,int startRow, int endRow, int rowNum) {  
    12         int pStartRow = startRow ;  
    13         int pEndRow = endRow ;  
    14         int targetRowFrom;  
    15         int targetRowTo;  
    16         int columnCount;  
    17         CellRangeAddress region = null;  
    18         int i;  
    19         int j;  
    20         
    21         if (pStartRow < 0 && pEndRow < 0) {
    22             return;
    23         } else if (pStartRow < 0) {
    24             pStartRow = 0;
    25         } else if (pEndRow < 0) {
    26             pEndRow = 0;
    27         }
    28         if (pStartRow>pEndRow) {  
    29             int x =  pEndRow;
    30             pEndRow = pStartRow;
    31             pStartRow = x;
    32         } 
    33         
    34         for (i = sheet.getNumMergedRegions()-1 ; i >=0 ; i--) {  
    35             region = sheet.getMergedRegion(i);  
    36             if ((region.getFirstRow() >= pStartRow) && (region.getLastRow() <= pEndRow)) {  
    37                 targetRowFrom = region.getFirstRow() + rowNum;  
    38                 targetRowTo = region.getLastRow() + rowNum;  
    39                 CellRangeAddress newRegion = region.copy();  
    40                 newRegion.setFirstRow(targetRowFrom);  
    41                 newRegion.setFirstColumn(region.getFirstColumn());  
    42                 newRegion.setLastRow(targetRowTo);  
    43                 newRegion.setLastColumn(region.getLastColumn());  
    44                 sheet.addMergedRegion(newRegion);  
    45             }  
    46         }  
    47         for (i = pEndRow; i >= pStartRow; i--) {  
    48             HSSFRow sourceRow = sheet.getRow(i);  
    49             columnCount = sourceRow.getLastCellNum();  
    50             if (sourceRow != null) {  
    51                 HSSFRow newRow = sheet.createRow(i + rowNum);  
    52                 newRow.setHeight(sourceRow.getHeight());  
    53                 for (j = 0; j < columnCount; j++) {  
    54                     HSSFCell templateCell = sourceRow.getCell(j);  
    55                     if (templateCell != null) {  
    56                         HSSFCell newCell = newRow.createCell(j);  
    57                         copyCell(templateCell, newCell);  
    58                     }  
    59                 }  
    60             }  
    61         }  
    62     }  
    63   
    64     private static void copyCell(HSSFCell srcCell, HSSFCell distCell) {  
    65         distCell.setCellStyle(srcCell.getCellStyle());  
    66         if (srcCell.getCellComment() != null) {  
    67             distCell.setCellComment(srcCell.getCellComment());  
    68         }  
    69         int srcCellType = srcCell.getCellType();  
    70         distCell.setCellType(srcCellType);  
    71         if (srcCellType == HSSFCell.CELL_TYPE_NUMERIC) {  
    72             if (HSSFDateUtil.isCellDateFormatted(srcCell)) {  
    73                 distCell.setCellValue(srcCell.getDateCellValue());  
    74             } else {  
    75                 distCell.setCellValue(srcCell.getNumericCellValue());  
    76             }  
    77         } else if (srcCellType == HSSFCell.CELL_TYPE_STRING) {  
    78             distCell.setCellValue(srcCell.getRichStringCellValue());  
    79         } else if (srcCellType == HSSFCell.CELL_TYPE_BLANK) {  
    80             // nothing21  
    81         } else if (srcCellType == HSSFCell.CELL_TYPE_BOOLEAN) {  
    82             distCell.setCellValue(srcCell.getBooleanCellValue());  
    83         } else if (srcCellType == HSSFCell.CELL_TYPE_ERROR) {  
    84             distCell.setCellErrorValue(srcCell.getErrorCellValue());  
    85         } else if (srcCellType == HSSFCell.CELL_TYPE_FORMULA) {  
    86             distCell.setCellFormula(srcCell.getCellFormula());  
    87         } else { // nothing29  
    88   
    89         }  
    90     }  
    移动行
    sheet.shiftRows(int startRow, int endRow, int n);
    //startRow与endRow用于选定移动区域,n用于指定向上(负数)或向下移动的行数,目标区域将被覆盖,原区域将清空。

    excel中的样式使用起来有些问题:
    1、最多创建3954个HSSFCellStyle对象
    2、HSSFCellStyle对象无法复用,多个cell引用同一个style,这些cell就是相同的style。
    cell.setCellStyle(style)后,若改变style的值,cell的样式会相应改变。

    在做项目中,HSSFCellStyle对象的个数过多,于是想到复用,结果所有的单元格都是相同的背景色。

     
    简单例子
     1     //在D盘新建一个excel2003文件aaa.xls,给sheet1中的单元格填值,最好从A到H列的1到10行单元格都填入如下公式:=COLUMN()+8*(ROW()-1)
     2     public static void main(String[] args) throws IOException {
     3         File file1 = new File("D:\\aaa.xls");
     4         File file2= new File("D:\\bbb.xls");
     5         InputStream is = new FileInputStream(file1);
     6         OutputStream os = new FileOutputStream(file2);// 取得输出流
     7         HSSFWorkbook wb = new HSSFWorkbook(is);
     8         is.close();
     9         HSSFSheet sheet;
    10         HSSFRow row;
    11         HSSFCell cell;
    12         sheet=wb.getSheetAt(0);
    13         int lastRowNum;
    14         short x = 0;
    15         if (sheet!=null) {
    16             lastRowNum=sheet.getLastRowNum();
    17             for (int rowIndex = 0; rowIndex <= lastRowNum; rowIndex++) {
    18                 row= sheet.getRow(rowIndex);
    19                 if (row!=null) {
    20                     short lastCellNum = row.getLastCellNum();
    21                     for (int celIndex = 0; celIndex <= lastCellNum; celIndex++) {
    22                         cell = row.getCell(celIndex);
    23                         if (cell!=null) {
    24                             HSSFCellStyle style = wb.createCellStyle();//最多3954个HSSFCellStyle对象
    25                             style.setFillForegroundColor(x);
    26                             cell.setCellValue(x);
    27                             x++;
    28                             style.setFillPattern((short) 1);
    29                             cell.setCellStyle(style);
    30                         }
    31                     }
    32                 }
    33             }
    34         }
    35         wb.write(os);
    36         os.flush();
    37         os.close();
    38     }
    39     //HSSFWorkbook,HSSFSheet,HSSFRow,HSSFCell的getxxx方法,都相应有createxxx方法
    40     //HSSFWorkbook,HSSFSheet有相应的构造方法

    运行这段代码你会发现,x从8到65才是真正的有用值,从8开始前几个是常用颜色,65是无颜色。
    将代码:HSSFCellStyle style = wb.createCellStyle();移动到for循环之前,你会发现都是一样的颜色了。
    字体颜色是一样的,加上如下代码你会发现字都没了,不是没了,只是字体颜色和背景色一样罢了。
    Font font = wb.createFont();
    font.setColor(x);
    style.setFont(font);

    样式
     1         //获取单元格一般样式的方法:
     2         HSSFCellStyle cellstyle    ;                                        //单元格样式
     3         cellstyle = cell.getCellStyle();                                //获取cellstyle
     4         short borderBottom = cellstyle.getBorderBottom();                //下边框
     5         short borderLeft = cellstyle.getBorderLeft();                    //左边框
     6         short borderRight = cellstyle.getBorderRight();                    //右边框
     7         short borderTop = cellstyle.getBorderTop();                        //上边框
     8         short background = cellstyle.getFillBackgroundColor();            //背景色
     9         short foreground = cellstyle.getFillForegroundColor();            //前景色
    10         short alignment = cellstyle.getAlignment();                        //水平对齐
    11         short verAlignment = cellstyle.getVerticalAlignment();             //垂直对齐
    12         boolean wrapText = cellstyle.getWrapText();                        //自动换行
    13         HSSFFont font = cellstyle.getFont(wb);                            //Font
    14         short color = font.getColor();                                    //颜色
    15         String fontName = font.getFontName();                            //字体
    16         short fontHeight = font.getFontHeightInPoints();                //字号
    17         short boldWeight = font.getBoldweight();                        //字形
    18         //对应的有相同的set方法

    你也许在复制行的代码中注意到了,
    在excel中日期也是以数字形式存储,
    需要借助于HSSFDateUtil.isCellDateFormatted(cell)判断是否为日期型。
    然后通过cell.getDateCellValue()来获取日期单元格的日期

    如果你需要将excel的信息都存入数据库中,你也许需要将Date转成String:
    Date D_temp = cell.getDateCellValue();
    SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS",java.util.Locale.US);//"yyyy-MM-dd HH:mm:ss SSS"可自行修改
    String cellValue = sdf.format(D_temp);
    回转:
    Date D_temp = sdf.parse(cellValue);

    有时需要获取行高和列宽:
    row.getHeightInPoints(); //Excel获取行高所使用单位为Point(点)
    sheet.getColumnWidth(colIndex); //列宽使用单位为Character(字符)的1/256
    关于点,字符,像素的换算关系,本人没有弄透。
    行高对应像素:Row Height(point)=Height Pixels * 0.75


    在复制行的方法中,对于合并单元格应该很好理解。
    合并单元格看做一个方形区域,用CellRangeAddress对象表示,它有4个属性:FirstRow,LastRow,FirstColumn,LastColumn
    构造方法:CellRangeAddress cra = new CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol);

     

  • 相关阅读:
    !ps之前一次执行的内容
    shortcut switch in terminal start pos & end pos
    百度词典搜索_dress code
    修杰楷_百度百科
    红米让夏新没活路了,
    绝杀600元以下智能手机的夏新小V二代-专栏-速途网
    李宗瑞_百度百科
    监制_百度百科
    文件上传~Uploadify上传控件
    知方可补不足~CSS中的几个伪元素
  • 原文地址:https://www.cnblogs.com/guodefu909/p/2740604.html
Copyright © 2020-2023  润新知