使用POI操作Excel和Word_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 使用POI操作Excel和Word

使用POI操作Excel和Word

 2013/8/8 19:08:14  ray_yui  程序员俱乐部  我要评论(0)
  • 摘要:前言:今天在项目中看到有小模块是上传Excel解释后保存到数据库的操作,好奇之下去了解了如何使用ApachePOI操纵Excel和Word,以下为小分享什么是POI?POI是Apache下的一个项目,是用Java编写的开源框架,提供API供开发者直接操作MicrosoftOffice(Excel,Word,PowerPoint...)POI为我们带来了什么?在很多的企业当中,储蓄数据是使用Excel文档的,因为Excel文档的格式方便,也能套用公式,而企业程序是存储在数据库当中
  • 标签:excel 使用 操作

前言:今天在项目中看到有小模块是上传Excel解释后保存到数据库的操作,好奇之下去了解了如何使用Apache POI操纵Excel和Word,以下为小分享


什么是POI?
      POI是Apache下的一个项目,是用Java编写的开源框架,提供API供开发者直接操作Microsoft Office(Excel,Word,PowerPoint...)

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

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

class="xml">
<!-- POI核心依赖 -->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>3.8</version>
</dependency>
<!-- 为POI支持Office Open XML -->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.8</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml-schemas</artifactId>
	<version>3.8</version>
</dependency>
<!-- 支持Word文档的操作 -->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-scratchpad</artifactId>
	<version>3.8</version>
</dependency>


      以下为操作Excel的测试类

package com.accentrix.ray;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Before;
import org.junit.Test;

public class TestExcel {

	private Workbook workbook;
	
	
	
	
	
	/*
	 * 由于Excel当中的单元格Cell存在类型,若获取类型错误 就会产生错误, 
	 * 所以通过此方法将Cell内容全部转换为String类型
	 */
	private String getCellValue(Cell cell) {
		String str = null;
		switch (cell.getCellType()) {
		case Cell.CELL_TYPE_BLANK:
			str = "";
			break;
		case Cell.CELL_TYPE_BOOLEAN:
			str = String.valueOf(cell.getBooleanCellValue());
			break;
		case Cell.CELL_TYPE_FORMULA:
			str = String.valueOf(cell.getCellFormula());
			break;
		case Cell.CELL_TYPE_NUMERIC:
			str = String.valueOf(cell.getNumericCellValue());
			break;
		case Cell.CELL_TYPE_STRING:
			str = String.valueOf(cell.getStringCellValue());
			break;
		default:
			str = null;
			break;
		}
		return str;
	}
	

	@Before
	public void setUp() throws InvalidFormatException, IOException {
		// 加载excel文件,自动判断是HSSF还是XSSF
		workbook = WorkbookFactory.create(new File("E:/aaa.xls"));
	}

	/*
	 * 读取一个已存在的Excel
	 */
	@Test
	public void testReadExcel() throws InvalidFormatException, IOException {

		// 获取第一个工作目录,下标从0开始
		Sheet sheet = workbook.getSheetAt(0);

		// 获取该工作目录最后一行的行数
		int lastRowNum = sheet.getLastRowNum();

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

			// 获取下标为i的行
			Row row = sheet.getRow(i);

			// 获取该行单元格个数
			int lastCellNum = row.getLastCellNum();

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

				// 获取下标为j的单元格
				Cell cell = row.getCell(j);

				// 调用获取方法
				String cellValue = this.getCellValue(cell);
			}
		}
	}

	/*
	 * 使用Foreach方式读取Excel
	 */
	@Test
	public void testForeachReadExcel() {
		// 根据sheet的名字获取
		Sheet sheet = workbook.getSheet("test");

		// 处了上面testReadExcel的方式读取以外,还支持foreach的方式读取
		for (Row row : sheet) {
			for (Cell cell : row) {
				String cellValue = this.getCellValue(cell);
				System.out.println(cellValue);
			}
		}
	}

	/*
	 * 创建简单的Excel
	 */
	@Test
	public void testWriteExcel() throws IOException {
		// 创建一个XSSF的Excel文件
		workbook = new XSSFWorkbook();
		FileOutputStream fos = new FileOutputStream("E:/test.xlsx");

		// 创建名称为test的工作目录
		Sheet sheet = workbook.createSheet("test");

		/*
		 * 创建1个10行x10列的工作目录
		 */
		for (int i = 0; i < 10; i++) {
			// 创建一行
			Row row = sheet.createRow(i);
			for (int j = 0; j < 10; j++) {
				// 创建一个单元格
				Cell cell = row.createCell(j);
				// 设置单元格value
				cell.setCellValue("test");

				// 此处为设置Excel的样式,设置单元格内容居中,
				// 但这样设置方式并不常用,请留意下面的方法
				CellStyle cs = workbook.createCellStyle();
				cs.setAlignment(CellStyle.ALIGN_CENTER);
				cell.setCellStyle(cs);

			}
		}

		// 将Excel写出到文件流
		workbook.write(fos);
	}

	/*
	 * 通过使用模板生成Excel文件,模板当中包含样式, 
	 * 这样我们只为模板填充数据就可以有相应的样式
	 */
	@Test
	public void testWriteExcelByTemplate() throws InvalidFormatException,
			IOException {
		String fileName = "test.xlsx";

		// 通过类加载器获取模板
		workbook = WorkbookFactory.create(this.getClass().getClassLoader()
				.getResourceAsStream(fileName));
		FileOutputStream fos = new FileOutputStream("E:/test.xlsx");

		Sheet sheet = workbook.getSheetAt(0);
		Row row = sheet.getRow(0);
		Cell cell = row.getCell(0);
		/*
		 * 此时可以通过getCellStyle()来获取到该单元格对象的样式,
		 * 获取到样式只要将此样式放入新创建Excel单元格中,
		 * 就可以完成样式的替换 获取可以直接填充此模板再进行输出,
		 * 注意插入新一行时,要使用sheet.shiftRows(0, 7, 1, true, true); 
		 * 这里代表从第0行到第7向下移动1行,保持宽度和高度
		 */
		CellStyle cellStyle = cell.getCellStyle();

		workbook.write(fos);
	}
}


      以下为操作Word的测试类

package com.accentrix.ray;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import junit.framework.Assert;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.Borders;
import org.apache.poi.xwpf.usermodel.LineSpacingRule;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestWord {

	// 生成Word2007版本
	private FileInputStream fis2007;
	private XWPFDocument doc2007;
	private XWPFWordExtractor word2007;

	// 生成Word2003版本
	private FileInputStream fis2003;
	private HWPFDocument doc2003;
	private WordExtractor word2003;

	// 创建Word输出流
	private FileOutputStream fos;

	@Before
	public void setUp() throws Exception {

		// 初始化2007版本
		fis2007 = new FileInputStream(new File("D:/test.docx"));
		doc2007 = new XWPFDocument(fis2007);
		word2007 = new XWPFWordExtractor(doc2007);

		// 初始化2003版本
		fis2003 = new FileInputStream(new File("D:/test2.doc"));
		doc2003 = new HWPFDocument(fis2003);
		word2003 = new WordExtractor(doc2003);

		// 初始化输出流
		fos = new FileOutputStream(new File("D:/testCreateWord.docx"));
	}

	@Test
	public void testReadWord2003() {
		// 直接通过getText()获取文本
		String text = word2003.getText();
		// 获取总页数
		doc2003.getSummaryInformation().getPageCount();
		// 获取总字数
		doc2003.getSummaryInformation().getWordCount();
		Assert.assertNotNull(text);
	}

	@Test
	public void testReadWord2007() {
		// 直接通过getText()获取文本
		String text = word2007.getText();

		// 获取总页数
		doc2007.getProperties().getExtendedProperties()
				.getUnderlyingProperties().getPages();

		// 获取去除空格的总页数
		doc2007.getProperties().getExtendedProperties()
				.getUnderlyingProperties().getCharacters();

		// 获取带空格的总页数
		doc2007.getProperties().getExtendedProperties()
				.getUnderlyingProperties().getCharactersWithSpaces();

		Assert.assertNotNull(text);
	}

	/*
	 * 演示如何创建Word文档
	 */
	@Test
	public void testWriteWord2007() throws IOException {
		XWPFDocument doc = new XWPFDocument();

		// 创建段落
		XWPFParagraph p1 = doc.createParagraph();
		// 设置样式,此时样式为一个正方形包围文字
		p1.setAlignment(ParagraphAlignment.CENTER);
		p1.setBorderBottom(Borders.DOUBLE);
		p1.setBorderTop(Borders.DOUBLE);
		p1.setBorderRight(Borders.DOUBLE);
		p1.setBorderLeft(Borders.DOUBLE);
		p1.setBorderBetween(Borders.SINGLE);
		p1.setVerticalAlignment(TextAlignment.TOP);

		// 创建1段文字,通过段落创建
		XWPFRun r1 = p1.createRun();
		// 设置是否粗体
		r1.setBold(true);
		r1.setText("The quick brown fox");
		r1.setBold(true);
		r1.setFontFamily("Courier");
		r1.setUnderline(UnderlinePatterns.DOT_DOT_DASH);
		r1.setTextPosition(100);

		XWPFParagraph p2 = doc.createParagraph();
		p2.setAlignment(ParagraphAlignment.RIGHT);

		p2.setBorderBottom(Borders.DOUBLE);
		p2.setBorderTop(Borders.DOUBLE);
		p2.setBorderRight(Borders.DOUBLE);
		p2.setBorderLeft(Borders.DOUBLE);
		p2.setBorderBetween(Borders.SINGLE);

		XWPFRun r2 = p2.createRun();
		r2.setText("Hello Hello Hello Hello Hello Hello Hello");
		r2.setStrike(true);
		r2.setFontSize(20);

		XWPFRun r3 = p2.createRun();
		r3.setText("World World World World World World World");
		r3.setStrike(true);
		r3.setFontSize(20);

		XWPFParagraph p3 = doc.createParagraph();
		p3.setWordWrap(true);
		// 设置该段落填充满本页,下面在显示新文本将在下一页显示
		p3.setPageBreak(true);

		p3.setAlignment(ParagraphAlignment.DISTRIBUTE);
		p3.setAlignment(ParagraphAlignment.BOTH);
		p3.setSpacingLineRule(LineSpacingRule.EXACT);

		p3.setIndentationFirstLine(600);

		doc.write(fos);
	}

	@After
	public void tearDown() throws IOException {
		if (fis2003 != null) {
			fis2003.close();
		}
		if (fis2007 != null) {
			fis2007.close();
		}
		if (fos != null) {
			fos.close();
		}
	}
}


总结:
      使用POI读取写出Excel文件非常方便,但写出的时候需要注意,是不包含样式的,但若然要结合样式来写出Excel或Word就会变得非常复杂,当有业务需求的时候建议上Apache POI的官网查看相关的API和Demo
发表评论
用户名: 匿名