POI读写Excel文件(转)
- 格式:doc
- 大小:72.00 KB
- 文档页数:19
poi读取Excel模板并修改模板内容与动态的增加⾏ 有时候我们可能遇到相当复杂的excel,⽐如表头的合并等操作,⼀种简单的⽅式就是直接代码合并(浪费时间),另⼀种就是写好模板,动态的向模板中增加⾏和修改指定单元格数据。
1.⼀个简单的根据模板sheet动态修改 原来的excel模板内容如下:现在的需求是动态的⽣成⽣成时间和⽣成⼈。
并且在第五⾏开始的数据列表增加5列:package cn.xm.exam.test;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import ermodel.Cell;import ermodel.XSSFCell;import ermodel.XSSFRow;import ermodel.XSSFSheet;import ermodel.XSSFWorkbook;public class DynamicOperateExcelUtils {public static void main(String[] args) throws IOException {// 读取源⽂件FileInputStream fis = new FileInputStream("G:/test.xlsx");XSSFWorkbook workBook = new XSSFWorkbook(fis);// 进⾏模板的克隆(接下来的操作都是针对克隆后的sheet)XSSFSheet sheet = workBook.cloneSheet(0);workBook.setSheetName(0, "sheet-0"); // 给sheet命名// 读取指定cell的内容XSSFCell nameCell = sheet.getRow(1).getCell(0);XSSFCell nameCell2 = sheet.getRow(1).getCell(1);System.out.println(nameCell.getStringCellValue());System.out.println(nameCell2.getStringCellValue());// 替换单元格内容(注意获取的cell的下标是合并之前的下标)replaceCellValue(sheet.getRow(1).getCell(2), "xxxxx时间");replaceCellValue(sheet.getRow(2).getCell(2), "xxxxx⼈");// 动态插⼊数据-增加⾏List<Map<String, Object>> datas = new ArrayList<>();for (int i = 0; i < 5; i++) {Map data = new HashMap<>();data.put("name", "name" + i);data.put("age", "age" + i);data.put("sex", "sex" + i);datas.add(data);}// 插⼊⾏sheet.shiftRows(4, 4 + datas.size(), datas.size(), true, false);// 第1个参数是指要开始插⼊的⾏,第2个参数是结尾⾏数,第三个参数表⽰动态添加的⾏数for (int i = 0; i < datas.size(); i++) {XSSFRow creRow = sheet.createRow(4 + i);creRow.setRowStyle(sheet.getRow(4).getRowStyle());creRow.createCell(0).setCellValue(datas.get(i).get("name").toString());creRow.createCell(1).setCellValue(datas.get(i).get("age").toString());creRow.createCell(2).setCellValue(datas.get(i).get("sex").toString());}// 输出为⼀个新的Excel,也就是动态修改完之后的excelString fileName = "test" + System.currentTimeMillis() + ".xlsx";OutputStream out = new FileOutputStream("G:" + "/" + fileName);workBook.removeSheetAt(0); // 移除workbook中的模板sheetworkBook.write(out);fis.close();out.flush();out.close();}/*** 替换单元格的内容,单元格的获取位置是合并单元格之前的位置,也就是下标都是合并之前的下表** @param cell* 单元格* @param value* 需要设置的值*/public static void replaceCellValue(Cell cell, Object value) {String val = value != null ? String.valueOf(value) : "";cell.setCellValue(val);}}结果: 上⾯需要注意的是:在替换的时候获取cell的时候获取的是合并单元格之前的cell位置,在动态增加⾏的时候⾏的其实和结束都是包含在内的。
使⽤poi读写Excel------demo package com.js.ai.modules.pointwall.interfac;import java.io.FileInputStream;import java.io.FileOutputStream;import ermodel.HSSFWorkbook;import ermodel.Cell;import ermodel.Row;import ermodel.Sheet;import ermodel.Workbook;import ermodel.XSSFWorkbook;public class TestExcel {/**** @Title: testReadExcel* @Description: 读取Excel* @return: void*/public void testReadExcel(){try {// 读取ExcelWorkbook wb = new XSSFWorkbook(new FileInputStream("D:\\javatest\\2.xlsx"));// 获取sheet(篇)数⽬for (int t = 0; t < wb.getNumberOfSheets(); t++) {Sheet sheet = wb.getSheetAt(t);Row row = null;int lastRowNum = sheet.getLastRowNum();// 循环读取for (int i = 0; i <= lastRowNum; i++) {row = sheet.getRow(i);if (row != null) {// 获取每⼀列的值for (int j = 0; j < row.getLastCellNum(); j++) {Cell cell = row.getCell(j);String value = getCellValue(cell);if (!value.equals("")) {System.out.print(value + "|");}}System.out.println();}}}} catch (Exception e) {e.printStackTrace();}}/**** @Title: getCellValue* @Description: 读取单元格的值* @param cell* @return* @return: String*/private String getCellValue(Cell cell){Object result="";switch(cell.getCellType()){case Cell.CELL_TYPE_STRING:result=cell.getStringCellValue();break;case Cell.CELL_TYPE_NUMERIC:result=cell.getNumericCellValue();break;case Cell.CELL_TYPE_BOOLEAN:result=cell.getBooleanCellValue();break;case Cell.CELL_TYPE_FORMULA:result=cell.getCellFormula();break;case Cell.CELL_TYPE_ERROR:result=cell.getErrorCellValue();break;case Cell.CELL_TYPE_BLANK:break;default:break;}return result.toString();}/**** @Title: testWriteExcel* @Description: 写⼊Excel⽂件* @return: void*/public void testWriteExcel() {String excelPath = "D:\\javatest\\2.xlsx";Workbook workbook=null;try {workbook = new XSSFWorkbook();} catch (Exception e) {System.out.println("创建Excel失败: ");e.printStackTrace();}if(workbook!=null){Sheet sheet=workbook.createSheet("测试数据");Row row0=sheet.createRow(0);for(int i=0;i<12;i++){Cell cell=row0.createCell(i, Cell.CELL_TYPE_STRING);cell.setCellValue("列标题");sheet.autoSizeColumn(i);//⾃动调整宽度}for (int rowNum = 1; rowNum < 16; rowNum++) {Row row = sheet.createRow(rowNum);for (int i = 0; i < 12; i++) {Cell cell = row.createCell(i, Cell.CELL_TYPE_STRING);cell.setCellValue("单元格" + String.valueOf(rowNum + 1)+ String.valueOf(i + 1));}}try {FileOutputStream outputStream = new FileOutputStream(excelPath);workbook.write(outputStream);outputStream.flush();outputStream.close();} catch (Exception e) {System.out .println("写⼊Excel失败: ");e.printStackTrace();}}}public static void main(String[] args) {TestExcel testExcel=new TestExcel();//testExcel.testReadExcel();testExcel.testWriteExcel();}} Workbook是⼀个接⼝,他有2个实现:HSSFWorkbook和XSSFWorkbook。
POI读写海量Excel(详细解读)目前处理Excel的开源javaAPI主要有两种,一是Jxl(Java Excel API),Jxl只支持Excel2021以下的版本。
另外一种是Apache的Jakarta POI,相比于Jxl,POI对微软办公文档的支持更加强大,但是它使用复杂,上手慢。
POI可支持更高的Excel版本2021。
对Excel的读取,POI有两种模式,一是用户模式,这种方式同Jxl的使用很类似,使用简单,都是将文件一次性读到内存,文件小的时候,没有什么问题,当文件大的时候,就会出现OutOfMemory的内存溢出问题。
第二种是事件驱动模式,拿Excel2021来说,其内容采用XML的格式来存储,所以处理excel就是解析XML,而目前使用事件驱动模式解析XML的API是SAX(Simple API for XML),这种模型在读取XML文档时,并没有将整个文档读入内存,而是按顺序将整个文档解析完,在解析过程中,会主动产生事件交给程序中相应的处理函数来处理当前内容。
因此这种方式对系统资源要求不高,可以处理海量数据。
笔者曾经做过测试,这种方法处理一千万条,每条五列的数据花费大约11分钟。
可见处理海量数据的文件事件驱动是一个很好的方式。
而本文中用到的AbstractExcel2021Reader、AbstractExcel2021Reader对Excel的读取都是采用这种POI的事件驱动模式。
至于Excel的写操作,对较高版本的Excel2021,POI提供了很好的支持,主要流程是第一步构建工作薄和电子表格对象,第二步在一个流中构建文本文件,第三步使用流中产生的数据替换模板中的电子表格。
这种方式也可以处理海量数据文件。
AbstractExcel2021Writer就是使用这种方式进行写操作。
对于写入较低版本的Excel2021,POI使用了用户模式来处理,就是将整个文档加载进内存,如果数据量大的话就会出现内存溢出的问题,Excel2021Writer就是使用这种方式。
java将excel文件转换成pdf文件的方法java将excel文件转换成pdf文件的方法java将excel文件转换成pdf文件的原理是使用POI来读取excel 的内容,将其写到pdf文件中。
实现难度有点大,主要是因为excel sheet结构不固定,内容也不固定,可能存在图片等,导致读excel比较复杂,真正实现还是比较复杂的。
下面是店铺为大家带来的'java将excel文件转换成pdf文件的方法,欢迎阅读。
java将excel文件转换成pdf文件的方法最近做一个项目,需要把excel文件转换成pdf文件,经过我查资料,无非使用两种方式:1 POI+Itext 2 Jacob来调用excel另存功能。
第一种方式,原理是使用POI来读取excel的内容,将其写到pdf 文件中。
实现难度有点大,主要是因为excel sheet结构不固定,内容也不固定,可能存在图片等,导致读excel比较复杂,真正实现还是比较复杂的。
第二种方式,原来是使用jacob来调用excel文件的另存为pdf的功能。
主要是熟悉jacob的API即可。
不需要精巧的编程技巧。
本文使用第二种方式,使用这种方式,需要在当前环境中安装office,pdf软件。
建议安装office 2010版本。
如果安装的07版本,还需要安装一个excel插件(SaveAsPDFand XPS.exe) 这个插件是微软官方的,链接如下:微软官方package com.bplead.module.sign.util;import com.jacob.activeX.ActiveXComponent;import .Dispatch;import .Variant;public class TransferTool {public static void els2pdf(String els,String pdf){System.out.println("Starting excel...");long start = System.currentTimeMillis();ActiveXComponent app = newActiveXComponent("Excel.Application");try {app.setProperty("Visible",false);Dispatch workbooks = app.getProperty("Workbooks").toDispatch();System.out.println("opening document:" + els);Dispatch workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, new Object[]{els, new Variant(false),new Variant(false)}, new int[3]).toDispatch();Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] {pdf, new Variant(57), new Variant(false),new Variant(57), new Variant(57), new Variant(false),new Variant(true), new Variant(57), new Variant(true),new Variant(true), new Variant(true) }, new int[1]);Variant f = new Variant(false);System.out.println("to pdf " + pdf);Dispatch.call(workbook, "Close", f);long end = System.currentTimeMillis();System.out.println("ed:" + (end - start)/1000 + " s");} catch (Exception e) {System.out.println("========Error:Operation fail:" + e.getMessage());}finally {if (app != null){app.invoke("Quit", new Variant[] {});}}}public static void main(String[] args) {els2pdf("f:ProjectT emplate.xlsx","f:pdf.pdf");}}运行以上环境,需要下载jacob的包,该包还包含2个dll文件,一个是jacob-1.17-x64.dll,这个是64位的,还有一个是jacob-1.17-x86.dll文件,这个是32位的。
(POI)Excel格式转Html格式Demo结构和引⽤的Jar包源代码(TestDemo.java)POI中将Excel转换为HTML⽅法仅能转换HSSFWorkBook类型(即03版xls),故可以先将读取的xlsx⽂件转换成xls⽂件再调⽤该⽅法统⼀处理package test;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.InputStream;import java.util.ArrayList;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.transform.OutputKeys;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import org.apache.poi.hssf.converter.ExcelToHtmlConverter;import ermodel.HSSFWorkbook;import ermodel.XSSFWorkbook;public class TestDemo {final static String path = "D:\\EclipseWorkspace\\ExcelToHtmlDemo\\ExcelToHtml\\";final static String file = "TestExcel.xlsx";private static final String EXCEL_XLS = "xls";private static final String EXCEL_XLSX = "xlsx";public static void main(String[] args){try{InputStream input = new FileInputStream(path +"/"+ file);HSSFWorkbook excelBook = new HSSFWorkbook();//判断Excel⽂件将07+版本转换为03版本if(file.endsWith(EXCEL_XLS)){ //Excel 2003excelBook = new HSSFWorkbook(input);}else if(file.endsWith(EXCEL_XLSX)){ // Excel 2007/2010Transform xls = new Transform();XSSFWorkbook workbookOld = new XSSFWorkbook(input); xls.transformXSSF(workbookOld, excelBook);}ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); //去掉Excel头⾏excelToHtmlConverter.setOutputColumnHeaders(false);//去掉Excel⾏号excelToHtmlConverter.setOutputRowNumbers(false);excelToHtmlConverter.processWorkbook(excelBook);Document htmlDocument = excelToHtmlConverter.getDocument();ByteArrayOutputStream outStream = new ByteArrayOutputStream();DOMSource domSource = new DOMSource(htmlDocument);StreamResult streamResult = new StreamResult(outStream);TransformerFactory tf = TransformerFactory.newInstance();Transformer serializer = tf.newTransformer();serializer.setOutputProperty(OutputKeys.ENCODING, "gb2312");serializer.setOutputProperty(OutputKeys.INDENT, "yes");serializer.setOutputProperty(OutputKeys.METHOD, "html");serializer.transform(domSource, streamResult);outStream.close();//Excel转换成HtmlString content = new String(outStream.toByteArray());System.out.println(content);}catch(Exception e) {e.printStackTrace();}}}源代码(Transform.java) 将xlsx⽂件转换成xls⽂件。
java使⽤poi(XSSFWorkbook)读取excel(.xlsx)⽂件经过⼀番搜索发现,java操纵excel⽂件常⽤的有jxl和poi两种⽅式,孰好孰坏看⾃⼰需求⽽定。
其中最主要的区别在于jxl不⽀持.xlsx,⽽poi⽀持.xlsx这⾥介绍的使⽤poi⽅式(XSSFWorkbook),实际上poi提供了HSSFWorkbook和XSSFWorkbook两个实现类。
区别在于HSSFWorkbook是针对.xls⽂件,XSSFWorkbook是针对.xslx⽂件。
⾸先明确⼀下基本概念: 先创建⼀个⼯作簿,⼀个⼯作簿可以有多个⼯作表,⼀个⼯作表可以有多个⾏,⼀个⾏可以有多个单元格 ⼯作簿 ----------->XSSFWorkbook ⼯作表 ----------->XSSFSheet ⾏ ----------->XSSFRow 单元格 ----------->XSSFCell下图为创建的student.xlsx的内容:导⼊依赖:<!--poi--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.0</version></dependency>读取student.xlsx⽂件代码:1package com.zjk.testexcel;23import ermodel.*;4import java.io.FileInputStream;5import java.io.IOException;67/**8 * @Auther: zjk9 * @Date: 2019/8/3010 * @Description:11*/12public class TestExcel1 {13public static void main(String[] args) {14try {15//创建⼯作簿16 XSSFWorkbook xssfWorkbook = new XSSFWorkbook(new FileInputStream("D:\\test-excel\\student.xlsx"));17 System.out.println("xssfWorkbook对象:" + xssfWorkbook);18//读取第⼀个⼯作表(这⾥的下标与list⼀样的,从0开始取,之后的也是如此)19 XSSFSheet sheet = xssfWorkbook.getSheetAt(0);20 System.out.println("sheet对象:" + sheet);21//获取第⼀⾏的数据22 XSSFRow row = sheet.getRow(0);23 System.out.println("row对象:" + row);24//获取该⾏第⼀个单元格的数据25 XSSFCell cell0 = row.getCell(0);26 System.out.println("cello对象:" + cell0);27 } catch (IOException e) {28 e.printStackTrace();29 }30 }31 }控制台输出结果:可以发现具体到⾏对象时,就解析成xml⽂件了xssfWorkbook对象: Name: /xl/workbook.xml - Content Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xmlsheet对象: Name: /xl/worksheets/sheet1.xml - Content Type: application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xmlrow对象: <xml-fragment r="1" spans="1:4" xmlns:r="/officeDocument/2006/relationships" xmlns:xdr="/drawingml/2006/spreadsheetDraw <main:c r="A1" t="s"> <main:v>0</main:v> </main:c> <main:c r="B1" t="s"> <main:v>1</main:v> </main:c> <main:c r="C1" t="s"> <main:v>2</main:v> </main:c> <main:c r="D1" t="s"><main:v>3</main:v></main:c></xml-fragment>cello对象:姓名以上可以实现了读取某⾏某单元格的数据,那么接下来就该读取整个表的所有数据了:package com.zjk.testexcel;import ermodel.XSSFCell;import ermodel.XSSFRow;import ermodel.XSSFSheet;import ermodel.XSSFWorkbook;import java.io.FileInputStream;import java.io.IOException;/*** @Auther: zjk* @Date: 2019/8/30* @Description:*/public class TestExcel2 {public static void main(String[] args) {try {//创建⼯作簿XSSFWorkbook xssfWorkbook = new XSSFWorkbook(new FileInputStream("D:\\test-excel\\student.xlsx"));System.out.println("xssfWorkbook对象:" + xssfWorkbook);//读取第⼀个⼯作表XSSFSheet sheet = xssfWorkbook.getSheetAt(0);System.out.println("sheet对象:" + sheet); //获取最后⼀⾏的num,即总⾏数。
java poi excel 读写摘要:1.Java POI 简介2.Java POI Excel 读写功能3.使用Java POI 读取Excel 文件4.使用Java POI 写入Excel 文件5.总结与展望正文:Java POI 是一个开源的Java 库,它允许Java 开发人员操作Microsoft Office 文档,如Word、Excel、PowerPoint 等。
其中,Java POI Excel 提供了读取和写入Excel 文件的功能。
1.Java POI 简介Java POI 是一个基于Apache License 2.0 协议的开源项目,它为Java 开发人员提供了一种操作Microsoft Office 文档的方法。
Java POI 支持读取和写入多种Office 文档格式,包括Excel、Word、PowerPoint 等。
通过使用Java POI,开发人员可以在不安装Microsoft Office 的情况下,对Office 文档进行操作。
2.Java POI Excel 读写功能Java POI Excel 提供了丰富的API,允许Java 开发人员对Excel 文件进行读取和写入操作。
Excel 文件主要包括两种类型:XLS 和XLSX。
Java POI 支持这两种文件格式,同时还支持读取和写入XML 格式的Excel 文件。
3.使用Java POI 读取Excel 文件使用Java POI 读取Excel 文件主要包括以下几个步骤:(1) 导入相关的Java POI 库:```javaimport ermodel.*;import ermodel.XSSFWorkbook;import java.io.FileInputStream;import java.io.IOException;```(2) 创建一个Workbook 对象,表示Excel 文件:```javaWorkbook workbook = new XSSFWorkbook(new FileInputStream("example.xlsx"));```(3) 获取工作表:```javaSheet sheet = workbook.getSheetAt(0);```(4) 遍历工作表中的行和列,获取单元格数据:```javafor (Row row : sheet) {for (Cell cell : row) {String cellValue = getCellValue(cell);System.out.print(cellValue + "t");}System.out.println();}```4.使用Java POI 写入Excel 文件使用Java POI 写入Excel 文件主要包括以下几个步骤:(1) 创建一个新的Excel 文件:```javaWorkbook workbook = new XSSFWorkbook();```(2) 添加一个新的工作表:```javaSheet sheet = workbook.createSheet("Sheet1");```(3) 创建行:```javaRow row = sheet.createRow(0);```(4) 创建单元格,并设置单元格数据:```javaCell cell = row.createCell(0);cell.setCellValue("Hello, World!");```(5) 将数据写入Excel 文件:```javatry (FileOutputStream fileOut = newFileOutputStream("output.xlsx")) {workbook.write(fileOut);} catch (IOException e) {e.printStackTrace();}```5.总结与展望Java POI 是一个功能强大的Java 库,它允许Java 开发人员轻松地操作Microsoft Office 文档,如Excel、Word、PowerPoint 等。
poi数据使用POI(Apache POI)是一个用于操作Microsoft Office格式文件(如doc、xls、ppt等)的Java API。
它提供了一组类和方法,使开发人员可以轻松地读取、写入和操作Office文档中的数据。
本文将介绍如何使用POI来处理poi数据。
二、POI数据读取1. 导入POI库首先,我们需要在项目中导入POI库。
可以下载POI的jar文件,然后将其添加到项目的classpath中。
2. 创建工作簿和工作表使用POI来读取poi数据之前,我们需要创建一个工作簿和一个工作表对象。
可以使用HSSFWorkbook和HSSFSheet类来分别代表工作簿和工作表。
3. 读取数据使用POI的API方法,我们可以逐行或逐列读取poi数据。
可以使用HSSFRow和HSSFCell类来分别代表行和单元格。
通过遍历行和列的方式,可以获取到相应的数据。
三、POI数据写入1. 创建工作簿和工作表与数据读取类似,我们首先需要创建一个工作簿和一个工作表对象。
可以使用HSSFWorkbook和HSSFSheet类来分别代表工作簿和工作表。
2. 写入数据使用POI的API方法,我们可以将数据写入到指定的单元格中。
可以使用HSSFRow和HSSFCell类来分别代表行和单元格。
可以通过设置单元格的值来进行数据的写入操作。
四、POI数据操作注意事项1. 数据格式转换在进行POI数据读取或写入操作时,需要注意数据的格式转换。
例如,将数字类型的数据转换为字符串,或将字符串类型的数据转换为日期类型。
2. 数据校验在写入数据之前,我们需要进行数据校验,确保所写入的数据符合需求。
例如,对于字符串类型的数据,可以进行长度、格式等校验。
3. 数据样式设置为了使POIpoi数据的呈现更加美观,我们可以设置数据的样式。
可以使用HSSFCellStyle类来设置单元格的字体、背景色、边框等样式。
本文介绍了如何使用POI对poi数据进行读取和写入操作。
NPOI读写Excel1、整个Excel表格叫做⼯作表:WorkBook(⼯作薄),包含的叫页(⼯作表):Sheet;⾏:Row;单元格Cell。
2、NPOI是POI的C#版本,NPOI的⾏和列的index都是从0开始3、POI读取Excel有两种格式⼀个是HSSF,另⼀个是XSSF。
HSSF和XSSF的区别如下:HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format.XSSF is the POI Project's pure Java implementation of the Excel 2007 OOXML (.xlsx) file format.即:HSSF适⽤2007以前的版本,XSSF适⽤2007版本及其以上的。
下⾯是⽤NPOI读写Excel的例⼦:ExcelHelper封装的功能主要是把DataTable中数据写⼊到Excel中,或者是从Excel读取数据到⼀个DataTable中。
ExcelHelper类:using System;using System.Collections.Generic;using System.Linq;using System.Text;using erModel;using erModel;using erModel;using System.IO;using System.Data;namespace NetUtilityLib{public class ExcelHelper : IDisposable{private string fileName = null; //⽂件名private IWorkbook workbook = null;private FileStream fs = null;private bool disposed;public ExcelHelper(string fileName){this.fileName = fileName;disposed = false;}///<summary>///将DataTable数据导⼊到excel中///</summary>///<param name="data">要导⼊的数据</param>///<param name="isColumnWritten">DataTable的列名是否要导⼊</param>///<param name="sheetName">要导⼊的excel的sheet的名称</param>///<returns>导⼊数据⾏数(包含列名那⼀⾏)</returns>public int DataTableToExcel(DataTable data, string sheetName, bool isColumnWritten){int i = 0;int j = 0;int count = 0;ISheet sheet = null;fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);if (fileName.IndexOf(".xlsx") > 0) // 2007版本workbook = new XSSFWorkbook();else if (fileName.IndexOf(".xls") > 0) // 2003版本workbook = new HSSFWorkbook();try{if (workbook != null){sheet = workbook.CreateSheet(sheetName);}else{return -1;}if (isColumnWritten == true) //写⼊DataTable的列名{IRow row = sheet.CreateRow(0);for (j = 0; j < data.Columns.Count; ++j){row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);}count = 1;}elsecount = 0;}for (i = 0; i < data.Rows.Count; ++i){IRow row = sheet.CreateRow(count);for (j = 0; j < data.Columns.Count; ++j){row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());}++count;}workbook.Write(fs); //写⼊到excelreturn count;}catch (Exception ex){Console.WriteLine("Exception: " + ex.Message);return -1;}}///<summary>///将excel中的数据导⼊到DataTable中///</summary>///<param name="sheetName">excel⼯作薄sheet的名称</param>///<param name="isFirstRowColumn">第⼀⾏是否是DataTable的列名</param>///<returns>返回的DataTable</returns>public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn){ISheet sheet = null;DataTable data = new DataTable();int startRow = 0;try{fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);if (fileName.IndexOf(".xlsx") > 0) // 2007版本workbook = new XSSFWorkbook(fs);else if (fileName.IndexOf(".xls") > 0) // 2003版本workbook = new HSSFWorkbook(fs);if (sheetName != null){sheet = workbook.GetSheet(sheetName);if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第⼀个sheet {sheet = workbook.GetSheetAt(0);}}else{sheet = workbook.GetSheetAt(0);}if (sheet != null){IRow firstRow = sheet.GetRow(0);int cellCount = stCellNum; //⼀⾏最后⼀个cell的编号即总的列数if (isFirstRowColumn){for (int i = firstRow.FirstCellNum; i < cellCount; ++i){ICell cell = firstRow.GetCell(i);if (cell != null){string cellValue = cell.StringCellValue;if (cellValue != null){DataColumn column = new DataColumn(cellValue);data.Columns.Add(column);}}}startRow = sheet.FirstRowNum + 1;}else{startRow = sheet.FirstRowNum;}//最后⼀列的标号int rowCount = stRowNum;for (int i = startRow; i <= rowCount; ++i)IRow row = sheet.GetRow(i);if (row == null) continue; //没有数据的⾏默认是null DataRow dataRow = data.NewRow();for (int j = row.FirstCellNum; j < cellCount; ++j){if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null dataRow[j] = row.GetCell(j).ToString();}data.Rows.Add(dataRow);}}return data;}catch (Exception ex){Console.WriteLine("Exception: " + ex.Message);return null;}}public void Dispose(){Dispose(true);GC.SuppressFinalize(this);}protected virtual void Dispose(bool disposing){if (!this.disposed){if (disposing){if (fs != null)fs.Close();}fs = null;disposed = true;}}}}测试代码:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data;namespace NPOIExcelExample{class Program{static DataTable GenerateData(){DataTable data = new DataTable();for (int i = 0; i < 5; ++i){data.Columns.Add("Columns_" + i.ToString(), typeof(string));}for (int i = 0; i < 10; ++i){DataRow row = data.NewRow();row["Columns_0"] = "item0_" + i.ToString();row["Columns_1"] = "item1_" + i.ToString();row["Columns_2"] = "item2_" + i.ToString();row["Columns_3"] = "item3_" + i.ToString();row["Columns_4"] = "item4_" + i.ToString();data.Rows.Add(row);}return data;}static void PrintData(DataTable data){if (data == null) return;for (int i = 0; i < data.Rows.Count; ++i)for (int j = 0; j < data.Columns.Count; ++j)Console.Write("{0} ", data.Rows[i][j]);Console.Write("\n");}}static void TestExcelWrite(string file){try{using (ExcelHelper excelHelper = new ExcelHelper(file)){DataTable data = GenerateData();int count = excelHelper.DataTableToExcel(data, "MySheet", true);if (count > 0)Console.WriteLine("Number of imported data is {0} ", count);}}catch (Exception ex){Console.WriteLine("Exception: " + ex.Message);}}static void TestExcelRead(string file){try{using (ExcelHelper excelHelper = new ExcelHelper(file)){DataTable dt = excelHelper.ExcelToDataTable("MySheet", true);PrintData(dt);}}catch (Exception ex){Console.WriteLine("Exception: " + ex.Message);}}static void Main(string[] args){string file = "..\\..\\myTest.xlsx";TestExcelWrite(file);TestExcelRead(file);}}}View Code签于这篇⽂章阅读量较⾼,更新⼀下我使⽤Aspose.Cells的另⼀个版本:PS:Aspose是要收费的using System;using System.Collections.Generic;using System.Data;using System.IO;using System.Linq;using System.Text;using Aspose.Cells;namespace NetUtilityLib{public static class ExcelHelper{public static int DataTableToExcel(DataTable data, string fileName, string sheetName, bool isColumnNameWritten) {int num = -1;try{Workbook workBook;Worksheet worksheet = null;if (File.Exists(fileName))workBook = new Workbook(fileName);elseworkBook = new Workbook();if (sheetName == null){worksheet = workBook.Worksheets[0];}else{sheetName = "Sheet1";workBook.Worksheets.RemoveAt(sheetName);worksheet = workBook.Worksheets.Add(sheetName);}}if (worksheet != null){worksheet.Cells.Clear();num = worksheet.Cells.ImportDataTable(data, isColumnNameWritten, 0, 0, false);workBook.Save(fileName);}}catch (Exception ex){Console.WriteLine(ex.Message);}return num;}public static void AddOneRowToExcel(DataRow dataRow, string fileName, string sheetName){try{Workbook workBook;if (File.Exists(fileName))workBook = new Workbook(fileName);elseworkBook = new Workbook();Worksheet worksheet=null;if (sheetName == null){worksheet = workBook.Worksheets[0];}else{worksheet = workBook.Worksheets[sheetName];}if (worksheet != null){worksheet.Cells.ImportDataRow(dataRow, worksheet.Cells.MaxDataRow + 1,0);//worksheet.Cells.ImportArray(dataArray, worksheet.Cells.MaxDataRow+1, 0, false);workBook.Save(fileName);}}catch (Exception ex){Console.WriteLine(ex.Message);}}public static DataTable ExcelToDataTable(string fileName, string sheetName, bool isFirstRowColumnName) {DataTable data = new DataTable();try{Workbook workbook = null;FileInfo fileInfo = new FileInfo(fileName);if (fileInfo.Extension.ToLower().Equals(".xlsx"))workbook = new Workbook(fileName, new LoadOptions(LoadFormat.Xlsx));else if (fileInfo.Extension.ToLower().Equals(".xls"))workbook = new Workbook(fileName, new LoadOptions(LoadFormat.Excel97To2003));if (workbook != null){Worksheet worksheet = null;if (sheetName != null){worksheet = workbook.Worksheets[sheetName];}else{worksheet = workbook.Worksheets[0];}data = worksheet.Cells.ExportDataTable(0, 0, worksheet.Cells.MaxRow+1, worksheet.Cells.MaxColumn+1, isFirstRowColumnName);return data;}}else{return data;}}catch (Exception ex){Console.WriteLine(ex.Message);}return data;}}}Excel相关DLL下载:参考:。
Java开发⼩技巧(六):使⽤ApachePOI读取Excel前⾔在数据仓库中,ETL最基础的步骤就是从数据源抽取所需的数据,这⾥所说的数据源并⾮仅仅是指数据库,还包括excel、csv、xml等各种类型的数据接⼝⽂件,⽽这些⽂件中的数据不⼀定是结构化存储的,⽐如各种各样的报表⽂件,往往是⼀些复杂的表格结构,其中不仅有我们需要的数据,还有⼀些冗余的、⽆价值的数据,这时我们就⽆法直接⽤⼀般数据加载⼯具直接读取⼊库了。
也许你会想,数据源导出⽂件前先处理好数据就⾏了。
然⽽,实际开发中数据源往往是多个的,⽽且涉及到不同的部门甚⾄公司,这其间难免会出现各种⿇烦,甚⾄有些数据⽂件还是纯⼿⼯处理的,不⼀定能给到你满意的数据格式。
所以我们不讨论谁该负责转换的问题,这⾥主要介绍如何使⽤Apache POI来从Excel数据⽂件中读取我们想要的数据,以及⽤Bean Validation对数据内容按照预定的规则进⾏校验。
⽂章要点:Apache POI是什么如何使⽤Apache POI读取Excel⽂件使⽤Bean Validation进⾏数据校验Excel读取⼯具类使⽤实例Apache POI是什么Apache POI是⽤Java编写的免费开源的跨平台的Java API,提供API给Java程式对Microsoft Office格式档案进⾏读和写的操作。
如何使⽤Apache POI处理Excel⽂件1、导⼊Maven依赖<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>3.17</version></dependency>2、创建Workbook实例这⾥需要注意的是Excel⽂档的版本问题,Excel2003及以前版本的⽂档使⽤HSSFWorkbook对象,Excel2007及之后版本使⽤HSSFWorkbook对象// Excel2003及以前版本Workbook workbook = new XSSFWorkbook(new FileInputStream(path));// Excel2007及之后版本Workbook workbook = new HSSFWorkbook(new FileInputStream(path));3、获取Sheet表格页对象Sheet是Excel⽂档中的⼯作簿即表格页⾯,读取前要先找到数据所在页⾯,可以通过标签名或者索引的⽅式获取指定Sheet对象// 按索引获取Sheet sheet = workbook.getSheetAt(index);// 按标签名获取4、获取Cell单元格对象// ⾏索引row和列索引col都是以 0 起始Cell cell = sheet.getRow(row).getCell(col);5、获取单元格内容获取单元格的值之前⾸先要获知单元格内容的类型,在Excel中单元格有6种类型:1. CELL_TYPE_BLANK :空值2. CELL_TYPE_BOOLEAN :布尔型3. CELL_TYPE_ERROR :错误4. CELL_TYPE_FORMULA :公式型5. CELL_TYPE_STRING:字符串型6. CELL_TYPE_NUMERIC:数值型各种类型的内容还需要进⼀步判断其数据格式,例如单元格的Type为CELL_TYPE_NUMERIC时,它有可能是Date类型,在Excel中的Date 类型是以Double类型的数字存储的,不同类型的值要调⽤cell对象相应的⽅法去获取,具体情况具体分析public Object getCellValue(Cell cell) {if(cell == null) {return null;}switch (cell.getCellType()) {case Cell.CELL_TYPE_STRING:return cell.getRichStringCellValue().getString();case Cell.CELL_TYPE_NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {return cell.getDateCellValue();} else {return cell.getNumericCellValue();}case Cell.CELL_TYPE_BOOLEAN:return cell.getBooleanCellValue();case Cell.CELL_TYPE_FORMULA:return formula.evaluate(cell).getNumberValue();default:return null;}}6、关闭Workbook对象workbook.close();使⽤Bean Validation进⾏数据校验当你要处理⼀个业务逻辑时,数据校验是你不得不考虑和⾯对的事情,程序必须通过某种⼿段来确保输⼊进来的数据从语义上来讲是正确的或者符合预定义的格式,⼀个Java程序⼀般是分层设计的,⽽不同的层可能是不同的开发⼈员来完成,这样就很容易出现不同的层重复进⾏数据验证逻辑,导致代码冗余等问题。
POI读写Excel文件(转)(2010-03-02 10:26:15)POI读写Excel文件(转)- -一、Excel基础二、HSSF概况三、通过usermodel读取文件四、通过usermodel写入文件五、通过eventusermodel读取文件六、HSSF电子表格结构七、通过HPSF读取文档属性八、文档摘要信息九、附录━━━━━━正文:━━━━━━在上一篇文章中,我们介绍了POI项目的基本概念,了解了如何用POI来读写OLE 2复合文档结构,并给出了两个简单的例子:用POI来读写Excel文件的Workbook流。
本文继续前文的话题,阐述如何用POI来读取/写入完整的Excel文件。
约定:POI项目2.0版现在已经接近正式发行阶段,开发进度迅速,不断有新的功能集成到原有的系统,同时也有对原有系统的修改。
为了保证本文的及时性,本文将按照最近的1.9开发版说明。
虽然编译最近的发行版源代码也能正常运行,但现在的代码和2.0的发行版会有一些出入。
一、Excel基础Microsoft Excel 97文件格式也被称为BIFF8,最近版本的Excel只对该格式作了少量的改动。
增加对新格式的支持除了增加项目的复杂性之外,唯一的效果也许只是不得不使每个用户升级代码,没有什么实际的好处。
因此,在下文说明中,凡是提到Excel 97格式的地方其实都是指Excel从97到XP的格式。
二、HSSF概况POI项目实现的Excel 97文件格式称为HSSF??也许你已经猜到,HSSF是Horrible SpreadSheet Format的缩写,也即“讨厌的电子表格格式”(微软使某些原本简单的事情过分复杂,同时又过分简单地处理了某些原本需要灵活性的事情,让人不胜佩服!)也许HSSF 的名字有点滑稽,就本质而言它是一个非常严肃、正规的API。
通过HSSF,你可以用纯Java 代码来读取、写入、修改Excel文件。
前面一篇文章提到了POIFS,那么HSSF和POIFS又有什么关系呢?就象其他POI的API一样,HSSF建立在POIFS的基础上,因此在HSSF内的有些代码和前文的某些代码很相似。
不过,当我们编写基于HSSF API的代码时,一般不需要了解POIFS API的细节。
HSSF为读取操作提供了两类API:usermodel和eventusermodel,即“用户模型”和“事件-用户模型”。
前者很好理解,后者比较抽象,但操作效率要高得多。
usermodel主要有ermodel和org.apache.poi.hssf.eventusermodel包实现(在HSSF的早期版本中,org.apache.poi.hssf.eventusermodel属于eventmodel包)。
usermodel包把Excel文件映射成我们熟悉的结构,诸如Workbook、Sheet、Row、Cell 等,它把整个结构以一组对象的形式保存在内存之中。
eventusermodel要求用户熟悉文件格式的底层结构,它的操作风格类似于XML的SAX API和AWT的事件模型(这就是eventusermodel名称的起源),要掌握窍门才能用好。
另外,eventusermodel的API只提供读取文件的功能,也就是说不能用这个API来修改文件。
三、通过usermodel读取文件用HSSF的usermodel读取文件很简单。
首先创建一个InputStream,然后创建一个HSSFWorkbook:InputStream myxls = new FileInputStr eam(”workbook.xls”));HSSFWorkbook wb = new HSSFWorkbook(myxls);有了HSSFWorkbook实例,接下来就可以提取工作表、工作表的行和列,例如:HSSFSheet sheet = wb.getSheetAt(0); // 第一个工作表HSSFRow row = sheet.getRow(2); // 第三行HSSFCell cell = row.getCell((short)3); // 第四个单元格上面这段代码提取出第一个工作表第三行第四单元格。
利用单元格对象可以获得它的值,提取单元格的值时请注意它的类型:if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {(”单元格是字符串,值是:” + cell.getStringCellValue());} else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {(”单元格是数字,值是:” + cell.getCellValue());} else () {(”单元格的值不是字符串或数值。
”);}如果搞错了数据类型,程序将遇到异常。
特别地,用HSSF处理日期数据要小心。
Excel 内部以数值的形式保存日期数据,区别日期数据的唯一办法是通过单元格的格式(如果你曾经在Excel中设置过日期格式,应该明白这是什么意思)。
因此,对于包含日期数据的单元格,cell.getCellType()将返回HSSFCell.CELL_TYPE_NUMERIC,不过利用工具函数HSSFDateUtil.isCellDateFormatted(cell)可以判断出单元格的值是否为日期。
isCellDateFormatted函数通过比较单元格的日期和Excel的内置日期格式得出结论??可以想象,按照这种判断方法,很多时候isCellDateFormatted函数会返回否定的结论,存在一定的误判可能。
本文附录包含了一个在Servlet环境中利用HSSF创建和返回Excel工作簿的实例。
四、通过usermodel写入文件写入XLS文件比读取XLS文件还要简单。
创建一个HSSFWorkbook实例,然后在适当的时候创建一个把文件写入磁盘的OutputStream,但延迟到处理结束时创建OutputStream 也可以:HSSFWorkbook wb = new HSSFWorkbook();FileOutputStream fileOut= new FileOutputStream(”workbook.xls”);wb.write(fileOut);fileOut.close();创建工作表及其内容必须从相应的父对象出发,例如:HSSFSheet sheet = wb.createSheet();HSSFRow row = sheet.createRow((short)0);HSSFCell cell = row.createCell((short)0);cell.setCellValue(1);row.createCell((short)1).setCellValue(1.2);row.createCell((short)2).setCellValue(”一个字符串”);row.createCell((short)3).setCellValue(true);如果要设置单元格的样式,首先要创建一个样式对象,然后把它指定给一个单元格??或者把它指定给多个具有相同样式的单元格,例如,如果Excel表格中有一个摘要行,摘要行的数据必须是粗体、斜体,你可以创建一个summaryRowStyle样式对象,然后把这个样式指定给所有摘要行上的单元格。
注意,CellFormat和CellStyle对象是工作簿对象的成员,单元格对象只是引用它们。
…HSSFCellStyle style = workbook.createCellStyle();style.setDataFormat(HSSFDataFormat.getBuiltinFormat(”($#,##0_);[Red]($#,##0)”));style.setFillBackgroundColor(HSSFColor.AQUA.index);style.setFillPattern(HSSFCellStyle.BIG_SPOTS);…someCell.setCellStyle(style);someOtherCell.setCellStyle(style);版本较新的HSSF允许使用数量有限的Excel公式。
这一功能目前还是“Beta级质量”,正式使用之前务必仔细测试。
指定公式的方式类如:someCell.setCellFormula(SUM(A1:A2:);。
当前,公式中已经可以调用所有内建的函数或操作符,但逻辑操作符和函数(例如IF 函数)除外,这部分功能目前还在开发之中。
五、通过eventusermodel读取文件通过eventusermodel读取文件要比使用usermodel复杂得多,但效率也要高不少,因为它要求应用程序一边读取数据,一边处理数据。
eventusermodel实际上模拟了DOM环境下SAX处理XML文档的办法,应用程序首先要注册期望处理的数据,eventusermodel将在遇到匹配的数据结构时回调应用程序注册的方法。
使用eventusermodel最大的困难在于你必须熟悉Excel工作簿的内部结构。
在HSSF中,低层次的二进制结构称为记录(Record)。
记录有不同的类型,每一种类型由org.apache.poi.hssf.record包中的一个Java类描述。
例如,BOFRecord记录表示Workbook或Sheet区域的开始,RowRecord表示有一个行存在并保存其样式信息。
所有具有CellValueRecordInterface接口的记录表示Excel的单元格,包括NumericRecord、LabelSSTRecord和FormulaRecord(还有其他一些,其中部分已被弃置不用,部分用于优化处理,但一般而言,HSSF可以转换它们)。
下面是一个注册事件处理句柄的例子:private EventRecordFactory factory = new EventRecordFactory();factory.registerListener(new ERFListener() {public boolean processRecord(Record rec) {(got BOF Record);return true;}}, new short[] {BOFRecord.sid});factory.processRecords(someInputStream);六、HSSF电子表格结构如前所述,HSSF建立在POIFS的基础上。
具体地说,Excel 97+文件是OLE 2复合文档(OLE 2 Compound Document),底层的OLE 2复合文档保存了一个总是命名为Workbook (Excel 95除外,HSSF不支持Excel 95)的流。