使用POI操作Excel和Word

前言:今天在项目中看到有小模块是上传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

2019-03-08 21:57

知识点

相关教程

更多

POI 操作 Excel的主要API

Java Aspose Cells 是一种纯粹的Java授权的Excel API

POI 操作Excel公式

在执行这个公式

lucene读取word,excel,pdf

前面在写lucene入门的时候,例子只能对txt文档建立索引,不能对word,excel,pdf建立索引,要读取这些文档的内容,需要额外的jar包,好在apache这个开源组织好,提供了对这些文档解析的开源jar包  索引和查询,我就不再写出来了,前面文章有,下面只将这三种文档的读取方法贴在下面  1.首先来看WORD文档:  这里用的是poi,相关jar包(http://poi.apache.o

solr建立pdf/word/excel索引的方法

      PS: 本文假设你已经成功的搭建了一个Solr服务器 步骤如下: (1)准备好一份Solr的源码,假设现在保存在c:\apache-solr-1.4.1\目录下 (2)从https://issues.apache.org/jira/browse/SOLR-284 上下载最新的rich.patch, libs.zip和test-files.zip三个文件 (3)解压libs.zip到c:

POI Excel电子表格处理

Writesheet.java

POI读取数据库数据到excel

让我们假设数据表是 emp_tbl 存有雇员信息是从MySQL数据库 test 中检索

poi导出Excel文件遇到的问题,请教高手

我本地可以保存,可有的测试那下载保存到本地报如下图错不能下载保存,有时直接打开也不好,请了解的指点下,谢拉

java jxl 操作excel 时老是这个错误

代码如下:  InputStream iso = new FileInputStream(filepath);//写入到FileInputStream  Workbook wb = Workbook.getWorkbook(iso);//得到工作薄  jxl.Sheet rs = wb.getSheet(0);  执行到此处时就报错了。错误如下:  java.lang.ClassCastExcep

Apache POI的使用

              Apache POI Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 结构: HSSF - 提供读写Microsoft Excel格式档案的功能。 XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。 HWPF - 提供读写Microsoft

孔浩老师poi视频教程

poi读取excel的数据,poi向excel写入数据,poi实现excel模板,poi实现基于对象列表输出到excel,poi读到excel文档到一个对象列表

关于POI模版的导入

现在有2个excel文件,一个是模版文件1.xls,里面有各种单元格的格式或者设置的什么的,另一个文件是有数据的等待操作的Excel文件2.xls,请问怎么通过java POI 代码实现将2.xls获得模版文件1.xls的各种单元格格式等,求详细代码谢谢!

JXLS根据excel模板生成EXCEL并下载

JXLS根据excel模板生成EXCEL并下载,jxl.jar,jxls-core-0.9.9.jar,jxls-reader-0.9.9.jar,poi-3.5-FINAL.jar(必须3.5以上的版本),其他jar根据提示可以去 http://jarvana.com/jarvana/ 查找,生成excel 传入模板文件 要生成的内容 生成文件 返回生成文件的完整路径

java+jsp来获取excel的数据?

首先我会在jsp页面上给用户一个上传组件,然后用户上传excel~然后自动后台去解析excel里面的数据,  我看了下网上的jxi和poi 都没怎么找到详细点的教程,希望有做过excel的师兄指点下..  我主要是想看下jxl或者poi  如何去获得excel中指定列的数据,因为我要把它放到数据库中的指定列里面去,然后jsp页面遍历显示..   不知道描述的清楚不.  问题补充:  还有 ,jxl

LeetCode:Word Break(DP)

题目地址:http://oj.leetcode.com/problems/word-break/ 简单的动态规划问题,采用自顶向下的备忘录方法,代码如下:     1 class Solution { 2 public: 3     bool dictContain(unordered_set<string> &dict, string s) 4     { 5

这种的EXCEL表格 怎么来解析??

如图的EXCEL表格 怎么来解析??

最新教程

更多

java线程状态详解(6种)

java线程类为:java.lang.Thread,其实现java.lang.Runnable接口。 线程在运行过程中有6种状态,分别如下: NEW:初始状态,线程被构建,但是还没有调用start()方法 RUNNABLE:运行状态,Java线程将操作系统中的就绪和运行两种状态统称为“运行状态” BLOCK:阻塞状态,表示线程阻塞

redis从库只读设置-redis集群管理

默认情况下redis数据库充当slave角色时是只读的不能进行写操作,如果写入,会提示以下错误:READONLY You can't write against a read only slave.  127.0.0.1:6382> set k3 111  (error) READONLY You can't write against a read only slave. 如果你要开启从库

Netty环境配置

netty是一个java事件驱动的网络通信框架,也就是一个jar包,只要在项目里引用即可。

Netty基于流的传输处理

​在TCP/IP的基于流的传输中,接收的数据被存储到套接字接收缓冲器中。不幸的是,基于流的传输的缓冲器不是分组的队列,而是字节的队列。 这意味着,即使将两个消息作为两个独立的数据包发送,操作系统也不会将它们视为两个消息,而只是一组字节(有点悲剧)。 因此,不能保证读的是您在远程定入的行数据

Netty入门实例-使用POJO代替ByteBuf

使用TIME协议的客户端和服务器示例,让它们使用POJO来代替原来的ByteBuf。

Netty入门实例-时间服务器

Netty中服务器和客户端之间最大的和唯一的区别是使用了不同的Bootstrap和Channel实现

Netty入门实例-编写服务器端程序

channelRead()处理程序方法实现如下

Netty开发环境配置

最新版本的Netty 4.x和JDK 1.6及更高版本

电商平台数据库设计

电商平台数据库表设计:商品分类表、商品信息表、品牌表、商品属性表、商品属性扩展表、规格表、规格扩展表

HttpClient 上传文件

我们使用MultipartEntityBuilder创建一个HttpEntity。 当创建构建器时,添加一个二进制体 - 包含将要上传的文件以及一个文本正文。 接下来,使用RequestBuilder创建一个HTTP请求,并分配先前创建的HttpEntity。

MongoDB常用命令

查看当前使用的数据库    > db    test  切换数据库   > use foobar    switched to db foobar  插入文档    > post={"title":"领悟书生","content":"这是一个分享教程的网站","date":new

快速了解MongoDB【基本概念与体系结构】

什么是MongoDB MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era. MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

windows系统安装MongoDB

安装 下载MongoDB的安装包:mongodb-win32-x86_64-2008plus-ssl-3.2.10-signed.msi,按照提示步骤安装即可。 安装完成后,软件会安装在C:\Program Files\MongoDB 目录中 我们要启动的服务程序就是C:\Program Files\MongoDB\Server\3.2\bin目录下的mongod.exe,为了方便我们每次启动,我

Spring boot整合MyBatis-Plus 之二:增删改查

基于上一篇springboot整合MyBatis-Plus之后,实现简单的增删改查 创建实体类 添加表注解TableName和主键注解TableId import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baom

分布式ID生成器【snowflake雪花算法】

基于snowflake雪花算法分布式ID生成器 snowflake雪花算法分布式ID生成器几大特点: 41bit的时间戳可以支持该算法使用到2082年 10bit的工作机器id可以支持1024台机器 序列号支持1毫秒产生4096个自增序列id 整体上按照时间自增排序 整个分布式系统内不会产生ID碰撞 每秒能够产生26万ID左右 Twitter的 Snowflake分布式ID生成器的JAVA实现方案