使用POI操作Excel和Word

2019-03-08 21:57|来源: 网络

前言:今天在项目中看到有小模块是上传Excel解释后保存到数据库的操作,好奇之下去了解了如何使用Apache POI操纵Excel和Word,以下为小分享
 
 
什么是POI?
   POI是Apache下的一个项目,是用Java编写的开源框架,提供API供开发者直接操作Microsoft Office(Excel,Word,PowerPoint...)

POI为我们带来了什么?
  在很多的企业当中,储蓄数据是使用Excel文档的,因为Excel文档的格式方便,也能套用公式,而企业程序是存储在数据库当中,这样就需要一种两者之间互相转换的方法,当企业刚开始使用信息化的管理系统时,也需要将Excel的数据录入到程序当中,这种需求是非常普遍的.

POI使用:
首先增加Maven的依赖

Xml代码
  1. <!-- POI核心依赖 -->  

  2. <dependency>  

  3.    <groupId>org.apache.poi</groupId>  

  4.    <artifactId>poi</artifactId>  

  5.    <version>3.8</version>  

  6. </dependency>  

  7. <!-- 为POI支持Office Open XML -->  

  8. <dependency>  

  9.    <groupId>org.apache.poi</groupId>  

  10.    <artifactId>poi-ooxml</artifactId>  

  11.    <version>3.8</version>  

  12. </dependency>  

  13. <dependency>  

  14.    <groupId>org.apache.poi</groupId>  

  15.    <artifactId>poi-ooxml-schemas</artifactId>  

  16.    <version>3.8</version>  

  17. </dependency>  

  18. <!-- 支持Word文档的操作 -->  

  19. <dependency>  

  20.    <groupId>org.apache.poi</groupId>  

  21.    <artifactId>poi-scratchpad</artifactId>  

  22.    <version>3.8</version>  

  23. </dependency>  


以下为操作Excel的测试类 
Java代码
  1. package com.accentrix.ray;  

  2.  

  3. import java.io.File;  

  4. import java.io.FileOutputStream;  

  5. import java.io.IOException;  

  6.  

  7. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;  

  8. import org.apache.poi.ss.usermodel.Cell;  

  9. import org.apache.poi.ss.usermodel.CellStyle;  

  10. import org.apache.poi.ss.usermodel.Row;  

  11. import org.apache.poi.ss.usermodel.Sheet;  

  12. import org.apache.poi.ss.usermodel.Workbook;  

  13. import org.apache.poi.ss.usermodel.WorkbookFactory;  

  14. import org.apache.poi.xssf.usermodel.XSSFWorkbook;  

  15. import org.junit.Before;  

  16. import org.junit.Test;  

  17.  

  18. public class TestExcel {  

  19.  

  20.    private Workbook workbook;  

  21.      

  22.      

  23.      

  24.      

  25.      

  26.    /*

  27.     * 由于Excel当中的单元格Cell存在类型,若获取类型错误 就会产生错误,

  28.     * 所以通过此方法将Cell内容全部转换为String类型

  29.     */  

  30.    private String getCellValue(Cell cell) {  

  31.        String str = null;  

  32.        switch (cell.getCellType()) {  

  33.        case Cell.CELL_TYPE_BLANK:  

  34.            str = "";  

  35.            break;  

  36.        case Cell.CELL_TYPE_BOOLEAN:  

  37.            str = String.valueOf(cell.getBooleanCellValue());  

  38.            break;  

  39.        case Cell.CELL_TYPE_FORMULA:  

  40.            str = String.valueOf(cell.getCellFormula());  

  41.            break;  

  42.        case Cell.CELL_TYPE_NUMERIC:  

  43.            str = String.valueOf(cell.getNumericCellValue());  

  44.            break;  

  45.        case Cell.CELL_TYPE_STRING:  

  46.            str = String.valueOf(cell.getStringCellValue());  

  47.            break;  

  48.        default:  

  49.            str = null;  

  50.            break;  

  51.        }  

  52.        return str;  

  53.    }  

  54.      

  55.  

  56.    @Before  

  57.    public void setUp() throws InvalidFormatException, IOException {  

  58.        // 加载excel文件,自动判断是HSSF还是XSSF  

  59.        workbook = WorkbookFactory.create(new File("E:/aaa.xls"));  

  60.    }  

  61.  

  62.    /*

  63.     * 读取一个已存在的Excel

  64.     */  

  65.    @Test  

  66.    public void testReadExcel() throws InvalidFormatException, IOException {  

  67.  

  68.        // 获取第一个工作目录,下标从0开始  

  69.        Sheet sheet = workbook.getSheetAt(0);  

  70.  

  71.        // 获取该工作目录最后一行的行数  

  72.        int lastRowNum = sheet.getLastRowNum();  

  73.  

  74.        for (int i = 0; i < lastRowNum; i++) {  

  75.  

  76.            // 获取下标为i的行  

  77.            Row row = sheet.getRow(i);  

  78.  

  79.            // 获取该行单元格个数  

  80.            int lastCellNum = row.getLastCellNum();  

  81.  

  82.            for (int j = 0; j < lastCellNum; j++) {  

  83.  

  84.                // 获取下标为j的单元格  

  85.                Cell cell = row.getCell(j);  

  86.  

  87.                // 调用获取方法  

  88.                String cellValue = this.getCellValue(cell);  

  89.            }  

  90.        }  

  91.    }  

  92.  

  93.    /*

  94.     * 使用Foreach方式读取Excel

  95.     */  

  96.    @Test  

  97.    public void testForeachReadExcel() {  

  98.        // 根据sheet的名字获取  

  99.        Sheet sheet = workbook.getSheet("test");  

  100.  

  101.        // 处了上面testReadExcel的方式读取以外,还支持foreach的方式读取  

  102.        for (Row row : sheet) {  

  103.            for (Cell cell : row) {  

  104.                String cellValue = this.getCellValue(cell);  

  105.                System.out.println(cellValue);  

  106.            }  

  107.        }  

  108.    }  

  109.  

  110.    /*

  111.     * 创建简单的Excel

  112.     */  

  113.    @Test  

  114.    public void testWriteExcel() throws IOException {  

  115.        // 创建一个XSSF的Excel文件  

  116.        workbook = new XSSFWorkbook();  

  117.        FileOutputStream fos = new FileOutputStream("E:/test.xlsx");  

  118.  

  119.        // 创建名称为test的工作目录  

  120.        Sheet sheet = workbook.createSheet("test");  

  121.  

  122.        /*

  123.         * 创建1个10行x10列的工作目录

  124.         */  

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

  126.            // 创建一行  

  127.            Row row = sheet.createRow(i);  

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

  129.                // 创建一个单元格  

  130.                Cell cell = row.createCell(j);  

  131.                // 设置单元格value  

  132.                cell.setCellValue("test");  

  133.  

  134.                // 此处为设置Excel的样式,设置单元格内容居中,  

  135.                // 但这样设置方式并不常用,请留意下面的方法  

  136.                CellStyle cs = workbook.createCellStyle();  

  137.                cs.setAlignment(CellStyle.ALIGN_CENTER);  

  138.                cell.setCellStyle(cs);  

  139.  

  140.            }  

  141.        }  

  142.  

  143.        // 将Excel写出到文件流  

  144.        workbook.write(fos);  

  145.    }  

  146.  

  147.    /*

  148.     * 通过使用模板生成Excel文件,模板当中包含样式,

  149.     * 这样我们只为模板填充数据就可以有相应的样式

  150.     */  

  151.    @Test  

  152.    public void testWriteExcelByTemplate() throws InvalidFormatException,  

  153.            IOException {  

  154.        String fileName = "test.xlsx";  

  155.  

  156.        // 通过类加载器获取模板  

  157.        workbook = WorkbookFactory.create(this.getClass().getClassLoader()  

  158.                .getResourceAsStream(fileName));  

  159.        FileOutputStream fos = new FileOutputStream("E:/test.xlsx");  

  160.  

  161.        Sheet sheet = workbook.getSheetAt(0);  

  162.        Row row = sheet.getRow(0);  

  163.        Cell cell = row.getCell(0);  

  164.        /*

  165.         * 此时可以通过getCellStyle()来获取到该单元格对象的样式,

  166.         * 获取到样式只要将此样式放入新创建Excel单元格中,

  167.         * 就可以完成样式的替换 获取可以直接填充此模板再进行输出,

  168.         * 注意插入新一行时,要使用sheet.shiftRows(0, 7, 1, true, true);

  169.         * 这里代表从第0行到第7向下移动1行,保持宽度和高度

  170.         */  

  171.        CellStyle cellStyle = cell.getCellStyle();  

  172.  

  173.        workbook.write(fos);  

  174.    }  

  175. }  



以下为操作Word的测试类

Java代码
  1. package com.accentrix.ray;  

  2.  

  3. import java.io.File;  

  4. import java.io.FileInputStream;  

  5. import java.io.FileOutputStream;  

  6. import java.io.IOException;  

  7.  

  8. import junit.framework.Assert;  

  9.  

  10. import org.apache.poi.hwpf.HWPFDocument;  

  11. import org.apache.poi.hwpf.extractor.WordExtractor;  

  12. import org.apache.poi.xwpf.extractor.XWPFWordExtractor;  

  13. import org.apache.poi.xwpf.usermodel.Borders;  

  14. import org.apache.poi.xwpf.usermodel.LineSpacingRule;  

  15. import org.apache.poi.xwpf.usermodel.ParagraphAlignment;  

  16. import org.apache.poi.xwpf.usermodel.TextAlignment;  

  17. import org.apache.poi.xwpf.usermodel.UnderlinePatterns;  

  18. import org.apache.poi.xwpf.usermodel.XWPFDocument;  

  19. import org.apache.poi.xwpf.usermodel.XWPFParagraph;  

  20. import org.apache.poi.xwpf.usermodel.XWPFRun;  

  21. import org.junit.After;  

  22. import org.junit.Before;  

  23. import org.junit.Test;  

  24.  

  25. public class TestWord {  

  26.  

  27.    // 生成Word2007版本  

  28.    private FileInputStream fis2007;  

  29.    private XWPFDocument doc2007;  

  30.    private XWPFWordExtractor word2007;  

  31.  

  32.    // 生成Word2003版本  

  33.    private FileInputStream fis2003;  

  34.    private HWPFDocument doc2003;  

  35.    private WordExtractor word2003;  

  36.  

  37.    // 创建Word输出流  

  38.    private FileOutputStream fos;  

  39.  

  40.    @Before  

  41.    public void setUp() throws Exception {  

  42.  

  43.        // 初始化2007版本  

  44.        fis2007 = new FileInputStream(new File("D:/test.docx"));  

  45.        doc2007 = new XWPFDocument(fis2007);  

  46.        word2007 = new XWPFWordExtractor(doc2007);  

  47.  

  48.        // 初始化2003版本  

  49.        fis2003 = new FileInputStream(new File("D:/test2.doc"));  

  50.        doc2003 = new HWPFDocument(fis2003);  

  51.        word2003 = new WordExtractor(doc2003);  

  52.  

  53.        // 初始化输出流  

  54.        fos = new FileOutputStream(new File("D:/testCreateWord.docx"));  

  55.    }  

  56.  

  57.    @Test  

  58.    public void testReadWord2003() {  

  59.        // 直接通过getText()获取文本  

  60.        String text = word2003.getText();  

  61.        // 获取总页数  

  62.        doc2003.getSummaryInformation().getPageCount();  

  63.        // 获取总字数  

  64.        doc2003.getSummaryInformation().getWordCount();  

  65.        Assert.assertNotNull(text);  

  66.    }  

  67.  

  68.    @Test  

  69.    public void testReadWord2007() {  

  70.        // 直接通过getText()获取文本  

  71.        String text = word2007.getText();  

  72.  

  73.        // 获取总页数  

  74.        doc2007.getProperties().getExtendedProperties()  

  75.                .getUnderlyingProperties().getPages();  

  76.  

  77.        // 获取去除空格的总页数  

  78.        doc2007.getProperties().getExtendedProperties()  

  79.                .getUnderlyingProperties().getCharacters();  

  80.  

  81.        // 获取带空格的总页数  

  82.        doc2007.getProperties().getExtendedProperties()  

  83.                .getUnderlyingProperties().getCharactersWithSpaces();  

  84.  

  85.        Assert.assertNotNull(text);  

  86.    }  

  87.  

  88.    /*

  89.     * 演示如何创建Word文档

  90.     */  

  91.    @Test  

  92.    public void testWriteWord2007() throws IOException {  

  93.        XWPFDocument doc = new XWPFDocument();  

  94.  

  95.        // 创建段落  

  96.        XWPFParagraph p1 = doc.createParagraph();  

  97.        // 设置样式,此时样式为一个正方形包围文字  

  98.        p1.setAlignment(ParagraphAlignment.CENTER);  

  99.        p1.setBorderBottom(Borders.DOUBLE);  

  100.        p1.setBorderTop(Borders.DOUBLE);  

  101.        p1.setBorderRight(Borders.DOUBLE);  

  102.        p1.setBorderLeft(Borders.DOUBLE);  

  103.        p1.setBorderBetween(Borders.SINGLE);  

  104.        p1.setVerticalAlignment(TextAlignment.TOP);  

  105.  

  106.        // 创建1段文字,通过段落创建  

  107.        XWPFRun r1 = p1.createRun();  

  108.        // 设置是否粗体  

  109.        r1.setBold(true);  

  110.        r1.setText("The quick brown fox");  

  111.        r1.setBold(true);  

  112.        r1.setFontFamily("Courier");  

  113.        r1.setUnderline(UnderlinePatterns.DOT_DOT_DASH);  

  114.        r1.setTextPosition(100);  

  115.  

  116.        XWPFParagraph p2 = doc.createParagraph();  

  117.        p2.setAlignment(ParagraphAlignment.RIGHT);  

  118.  

  119.        p2.setBorderBottom(Borders.DOUBLE);  

  120.        p2.setBorderTop(Borders.DOUBLE);  

  121.        p2.setBorderRight(Borders.DOUBLE);  

  122.        p2.setBorderLeft(Borders.DOUBLE);  

  123.        p2.setBorderBetween(Borders.SINGLE);  

  124.  

  125.        XWPFRun r2 = p2.createRun();  

  126.        r2.setText("Hello Hello Hello Hello Hello Hello Hello");  

  127.        r2.setStrike(true);  

  128.        r2.setFontSize(20);  

  129.  

  130.        XWPFRun r3 = p2.createRun();  

  131.        r3.setText("World World World World World World World");  

  132.        r3.setStrike(true);  

  133.        r3.setFontSize(20);  

  134.  

  135.        XWPFParagraph p3 = doc.createParagraph();  

  136.        p3.setWordWrap(true);  

  137.        // 设置该段落填充满本页,下面在显示新文本将在下一页显示  

  138.        p3.setPageBreak(true);  

  139.  

  140.        p3.setAlignment(ParagraphAlignment.DISTRIBUTE);  

  141.        p3.setAlignment(ParagraphAlignment.BOTH);  

  142.        p3.setSpacingLineRule(LineSpacingRule.EXACT);  

  143.  

  144.        p3.setIndentationFirstLine(600);  

  145.  

  146.        doc.write(fos);  

  147.    }  

  148.  

  149.    @After  

  150.    public void tearDown() throws IOException {  

  151.        if (fis2003 != null) {  

  152.            fis2003.close();  

  153.        }  

  154.        if (fis2007 != null) {  

  155.            fis2007.close();  

  156.        }  

  157.        if (fos != null) {  

  158.            fos.close();  

  159.        }  

  160.    }  

  161. }  



 
总结:
   使用POI读取写出Excel文件非常方便,但写出的时候需要注意,是不包含样式的,但若然要结合样式来写出Excel或Word就会变得非常复杂,当有业务需求的时候建议上Apache POI的官网查看相关的API和Demo
 
转自:http://ray-yui.iteye.com/blog/1922157

相关问答

更多
  • 用它的底层接口,EVentModel来操作会比较省内存,但代码写起来比较麻烦。9M左右就内存溢出的话,应该是你设置的Heap size太小了。增大Heap的大小也是必须的。 如果是xls的,用JExcel会比POI省内存。但它不支持2010。
  • JAVA是可以用POI操作WORD。EXCEL这些的 看下面这个能帮上你不 1、环境支持 1.1 添加poi支持:包下载地址 http://www.apache.org/dyn/closer.cgi/poi/release/ 1.2 POI对Excel文件的读取操作比较方便,POI还提供对Word的DOC格式文件的读取。但在它的发行版本中没有发布对Word支持的模块,需要另外下载一个POI的扩展的Jar包。下载地址为 http://www.ibiblio.org/maven2/org/textmining/ ...
  • 1、环境支持 1.1 添加poi支持:包下载地址http://www.apache.org/dyn/closer.cgi/poi/release/ 1.2 POI对Excel文件的读取操作比较方便,POI还提供对Word的DOC格式文件的读取。但在它的发行版本中没有发布对Word支持的模块,需要另外下载一个POI的扩展的Jar包。下载地址为http://www.ibiblio.org/maven2/org/textmining/tm-extractors/0.4/ 下载extractors-0.4_zip这 ...
  • // 创建工作簿 Workbook workBook = new HSSFWorkbook(); // 创建工作表 Sheet sheet = workBook.createSheet("new"); // 创建行,Excel中的第一行在poi中索引为0 Row row = sheet.createRow(0); // 创建单元格,Excel中的第一列在poi中索引为0 Cell cell = row.createCell(0); // 设置单元格内容 cell.setCellValue("行号/列号"); ...
  • JAVA POI操作EXCEL[2022-07-01]

    读入数据写入一个List,失败的放一个List。 在用poi输出失败记录的List
  • 看到你想要使用POI的实际代码。 这里有一些做一些出口: import java.util.Date; import java.util.List; import java.util.ListIterator; import java.util.StringTokenizer; import java.io.*; import org.apache.poi.hssf.usermodel.*; public class XLSExporter implements Exporter { /** ...