poi读写excel案例

合集下载

poi用法范文

poi用法范文

poi用法范文POI库的主要组成部分有以下几个:3. SXSSF(Streaming Usermodel API for Excel):用于处理大型Excel文件,通过将数据写入临时文件流来减少内存的使用。

使用POI库可以轻松地读取和写入Office文件的内容。

下面是一些POI的使用场景和示例:1. 读取Excel文件:使用POI可以读取Excel文件中的数据,如单元格的值、行和列的内容等。

以下是一个简单的读取Excel文件的示例:```FileInputStream file = new FileInputStream(newFile("example.xls"));Workbook workbook = new HSSFWorkbook(file);Sheet sheet = workbook.getSheetAt(0);Iterator<Row> rowIterator = sheet.iterator(;while (rowIterator.hasNext()Row row = rowIterator.next(;Iterator<Cell> cellIterator = row.cellIterator(;while (cellIterator.hasNext()Cell cell = cellIterator.next(;switch (cell.getCellType()case Cell.CELL_TYPE_STRING:System.out.print(cell.getStringCellValue( + "\t");break;case Cell.CELL_TYPE_NUMERIC:System.out.print(cell.getNumericCellValue( + "\t");break;}}System.out.println(;file.close(;``````Workbook workbook = new XSSFWorkbook(;Sheet sheet = workbook.createSheet("Sheet1");Row row = sheet.createRow(0);Cell cell = row.createCell(0);cell.setCellValue("Hello, POI!");FileOutputStream file = new FileOutputStream(new File("example.xlsx"));workbook.write(file);file.close(;``````FileInputStream file = new FileInputStream(newFile("example.docx"));XWPFDocument document = new XWPFDocument(file);List<XWPFParagraph> paragraphs = document.getParagraphs(;for (XWPFParagraph paragraph : paragraphs)System.out.println(paragraph.getText();file.close(;``````FileInputStream file = new FileInputStream(newFile("example.pptx"));XMLSlideShow slideshow = new XMLSlideShow(file);XSLFSlide[] slides = slideshow.getSlides(;for (XSLFSlide slide : slides)List<XSLFShape> shapes = slide.getShapes(;for (XSLFShape shape : shapes)if (shape instanceof XSLFTextShape) XSLFTextShape textShape = (XSLFTextShape) shape; System.out.println(textShape.getText();}}file.close(;```。

java的POI操作Excel文件

java的POI操作Excel文件

java的POI操作Excel文件(2)现在我要做的东西基本完成啦,我把这段时间使用POI的一些心得总结出来,希望能对和我遇到相同问题的朋友有所帮助,至于POI基本的使用方法,自己去看文档吧。

1、设置分页符的bugPOI里的HSSFSheet类提供了setRowBreak方法可以设置Sheet的分页符。

Bug:如果你要设置分页符的Sheet是本来就有的,并且你没有在里面插入过分页符,那么调用setRowBreak时POI会抛出空指针的异常。

解决方法:在Excel里给这个sheet插入一个分页符,用POI打开后再把它删掉,然后你就可以随意插入分页符了。

如果sheet是由POI生成的则没有这个问题。

我跟踪了setRowBreak的源代码,发现是Sheet.Java下的PageBreakRecord rowBreaks这个变量在搞鬼,如果Sheet里原来没有分页符,开发这个模块的那位兄台忘了为这个对象new实例,所以只能我们先手工给Excel插入一个分页符来触发POI为rowBreaks创建实例。

2、如何拷贝行我在的POI用户论坛翻遍了每个相关的帖子,找遍了api,也没看到一个拷贝行的方法,没办法,只能自己写://注:this.fWorkbook是一个HSSHWorkbook,请自行在外部newpublic void copyRows(String pSourceSheetName,String pTargetSheetName,int pStartRow, int pEndRow,int pPosition){HSSFRow sourceRow = null;HSSFRow targetRow = null;HSSFCell sourceCell = null;HSSFCell targetCell = null;HSSFSheet sourceSheet = null;HSSFSheet targetSheet = null;Region region = null;int cType;int i;short j;int targetRowFrom;int targetRowTo;if ((pStartRow == -1) || (pEndRow == -1)){return;}sourceSheet = this.fWorkbook.getSheet(pSourceSheetName);targetSheet = this.fWorkbook.getSheet(pTargetSheetName);//拷贝合并的单元格for (i = 0; i < sourceSheet.getNumMergedRegions(); i++){region = sourceSheet.getMergedRegionAt(i);if ((region.getRowFrom() >= pStartRow) && (region.getRowTo() <= pEndRow)) {targetRowFrom = region.getRowFrom() - pStartRow + pPosition; targetRowTo = region.getRowTo() - pStartRow + pPosition;region.setRowFrom(targetRowFrom);region.setRowTo(targetRowTo);targetSheet.addMergedRegion(region);}}//设置列宽for (i = pStartRow; i <= pEndRow; i++){sourceRow = sourceSheet.getRow(i);if (sourceRow != null){for (j = sourceRow.getFirstCellNum(); j < sourceRow.getLastCellNum(); j++) {targetSheet.setColumnWidth(j, sourceSheet.getColumnWidth(j));}break;}}//拷贝行并填充数据for (;i <= pEndRow; i++){sourceRow = sourceSheet.getRow(i);if (sourceRow == null){continue;}targetRow = targetSheet.createRow(i - pStartRow + pPosition);targetRow.setHeight(sourceRow.getHeight());for (j = sourceRow.getFirstCellNum(); j < sourceRow.getLastCellNum(); j++)sourceCell = sourceRow.getCell(j);if (sourceCell == null){continue;}targetCell = targetRow.createCell(j);targetCell.setEncoding(sourceCell.getEncoding());targetCell.setCellStyle(sourceCell.getCellStyle());cType = sourceCell.getCellType();targetCell.setCellType(cType);switch (cType){case HSSFCell.CELL_TYPE_BOOLEAN:targetCell.setCellValue(sourceCell.getBooleanCellValue());break;case HSSFCell.CELL_TYPE_ERROR:targetCell.setCellErrorV alue(sourceCell.getErrorCellValue());break;case HSSFCell.CELL_TYPE_FORMULA://parseFormula这个函数的用途在后面说明targetCell.setCellFormula(parseFormula(sourceCell.getCellFormula()));break;case HSSFCell.CELL_TYPE_NUMERIC:targetCell.setCellValue(sourceCell.getNumericCellV alue());break;case HSSFCell.CELL_TYPE_STRING:targetCell.setCellValue(sourceCell.getStringCellValue());break;}}}}这个函数有两个问题暂时无法解决:a、只能在同一个Workbook里面使用,跨Workbook总是拷不过去,不知道为什么?b、由于在拷贝行时也把行高也拷过去了,如果往这些单元格里写入的数据长度超过单元格长度,那么他们不会自动调整行高!3、公式的问题POI对Excel公式的支持是相当好的,但是我发现一个问题,如果公式里面的函数不带参数,比如now()或today(),那么你通过getCellFormula()取出来的值就是now(ATTR(semiV olatile))和today(ATTR(semiV olatile)),这样的值写入Excel是会出错的,这也是我上面copyRow的函数在写入公式前要调用parseFormula的原因,parseFormula这个函数的功能很简单,就是把ATTR(semiVolatile)删掉,我把它的代码贴出来:private String parseFormula(String pPOIFormula){final String cstReplaceString = "ATTR(semiV olatile)"; //$NON-NLS-1$StringBuffer result = null;int index;result = new StringBuffer();index = pPOIFormula.indexOf(cstReplaceString);if (index >= 0){result.append(pPOIFormula.substring(0, index));result.append(pPOIFormula.substring(index + cstReplaceString.length()));}else{result.append(pPOIFormula);}return result.toString();}至于为什么会出现ATTR(semiVolatile),还需要大家的探索精神!4、向Excel写入图片的问题。

poi读取Excel模板并修改模板内容与动态的增加行

poi读取Excel模板并修改模板内容与动态的增加行

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(详细解读)

POI读写海量Excel(详细解读)

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就是使用这种方式。

easy poi 例子

easy poi 例子

easy poi 例子POI是一个开源的Java库,用于操作各种Office文档,如Excel、Word和PowerPoint。

它提供了简单易用的API,使得处理这些文件变得非常简单和高效。

使用POI,我们可以轻松地读取和写入Excel文件。

下面是一个简单的POI示例,演示如何读取Excel文件中的数据并输出到控制台上:```javaimport ermodel.*;import ermodel.XSSFWorkbook;import java.io.FileInputStream;import java.io.IOException;public class ExcelReader {public static void main(String[] args) {String filePath = "path/to/excel/file.xlsx";try (FileInputStream fis = new FileInputStream(filePath);Workbook workbook = new XSSFWorkbook(fis)) {Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表DataFormatter dataFormatter = new DataFormatter();for (Row row : sheet) {for (Cell cell : row) {String cellValue = dataFormatter.formatCellValue(cell);System.out.print(cellValue + " ");}System.out.println();}} catch (IOException e) {e.printStackTrace();}}}```在上面的示例中,我们首先指定要读取的Excel文件的路径。

ApachePOI4.0.1版本写入普通Excel文件(兼容xls和xlsx)(四)

ApachePOI4.0.1版本写入普通Excel文件(兼容xls和xlsx)(四)

ApachePOI4.0.1版本写⼊普通Excel⽂件(兼容xls和xlsx)(四)⼀般在公司写项⽬,写⼊Excel时会有这样的场景:前台页⾯上有⼀个导出按钮,点击后将后台某张表⾥的数据以Excel的形式导出,导出的Excel⽂件通过浏览器下载。

基于最新的Apache POI 4.0.1版本来总结⼀下写⼊Excel的过程。

代码前准备:添加4.0.1 poi maven依赖<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.springbootemaildemo</groupId><artifactId>springboot-email-demo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>springboot-email-demo</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.6.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.7.0</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.7.0</version></dependency><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.11.3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.41</version></dependency><dependency><groupId>mons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version></dependency><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.8.3</version></dependency><dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId><version>1.0</version></dependency><!--poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.1</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin></plugins></build></project>DataVo(数据封装类)package com.springbootemaildemo.excel.b;/*** 读取Excel时,封装读取的每⼀⾏的数据*/public class DataVo {/*** 姓名*/private String name;/*** 年龄*/private Integer age;public String getName() {return name;}public void setName(String name) { = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}ExcelWriter(写⼊excel⽂件主要代码类)package com.springbootemaildemo.excel.b;import ermodel.*;import org.apache.poi.xssf.streaming.SXSSFWorkbook; import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ExcelWriter {private static List<String> CELL_HEADS; //列头static {// 类装载时就载⼊指定好的列头信息,如有需要,可以考虑做成动态⽣成的列头CELL_HEADS = new ArrayList<>();CELL_HEADS.add("姓名");CELL_HEADS.add("年龄");}/*** ⽣成Excel并写⼊数据信息** @param dataList 数据列表* @return 写⼊数据后的⼯作簿对象*/public static Workbook exportData(List<DataVo> dataList) {// ⽣成xlsx的ExcelWorkbook workbook = new SXSSFWorkbook();// 如需⽣成xls的Excel,请使⽤下⾯的⼯作簿对象,注意后续输出时⽂件后缀名也需更改为xls //Workbook workbook = new HSSFWorkbook();// ⽣成Sheet表,写⼊第⼀⾏的列头Sheet sheet = buildDataSheet(workbook);//构建每⾏的数据内容int rowNum = 1;for (Iterator<DataVo> it = dataList.iterator(); it.hasNext(); ) {DataVo data = it.next();if (data == null) {continue;}//输出⾏数据Row row = sheet.createRow(rowNum++);convertDataToRow(data, row);}return workbook;}/*** ⽣成sheet表,并写⼊第⼀⾏数据(列头)** @param workbook ⼯作簿对象* @return 已经写⼊列头的Sheet*/private static Sheet buildDataSheet(Workbook workbook) {Sheet sheet = workbook.createSheet();// 设置列头宽度for (int i = 0; i < CELL_HEADS.size(); i++) {sheet.setColumnWidth(i, 4000);}// 设置默认⾏⾼sheet.setDefaultRowHeight((short) 400);// 构建头单元格样式CellStyle cellStyle = buildHeadCellStyle(sheet.getWorkbook());// 写⼊第⼀⾏各列的数据Row head = sheet.createRow(0);for (int i = 0; i < CELL_HEADS.size(); i++) {Cell cell = head.createCell(i);cell.setCellValue(CELL_HEADS.get(i));cell.setCellStyle(cellStyle);}return sheet;}/*** 设置第⼀⾏列头的样式** @param workbook ⼯作簿对象* @return 单元格样式对象*/private static CellStyle buildHeadCellStyle(Workbook workbook) {CellStyle style = workbook.createCellStyle();//对齐⽅式设置style.setAlignment(HorizontalAlignment.CENTER);//边框颜⾊和宽度设置style.setBorderBottom(BorderStyle.THIN);style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 下边框style.setBorderLeft(BorderStyle.THIN);style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 左边框style.setBorderRight(BorderStyle.THIN);style.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 右边框style.setBorderTop(BorderStyle.THIN);style.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 上边框//设置背景颜⾊style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());style.setFillPattern(FillPatternType.SOLID_FOREGROUND);//粗体字设置Font font = workbook.createFont();font.setBold(true);style.setFont(font);return style;}/*** 将数据转换成⾏** @param data 源数据* @param row ⾏对象* @return*/private static void convertDataToRow(DataVo data, Row row) {int cellNum = 0;Cell cell;// 姓名cell = row.createCell(cellNum++);cell.setCellValue(null == data.getName() ? "" : data.getName());// 年龄cell = row.createCell(cellNum++);if (null != data.getAge()) {cell.setCellValue(data.getAge());} else {cell.setCellValue("");}}}Controllerpackage com.springbootemaildemo.excel.b;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.extern.slf4j.Slf4j;import mons.collections4.CollectionUtils;import ermodel.DateUtil;import ermodel.Workbook;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.OutputStream;import java.util.ArrayList;import java.util.Date;import java.util.List;@Slf4j@RestController@RequestMapping("/excel/b")@Api("导出Excel")public class ExcelFileController {private static final Logger logger =LoggerFactory.getLogger(ExcelFileController.class); @GetMapping("/exportExcel")public void exportExcel(HttpServletRequest request, HttpServletResponse response) { Workbook workbook = null;OutputStream out = null;try {// todo 根据业务需求获取需要写⼊Excel的数据列表 dataListList<DataVo> dataList = new ArrayList<>();//把数据加载到dataList中即可// ⽣成Excel⼯作簿对象并写⼊数据workbook = ExcelWriter.exportData(dataList);// 写⼊Excel⽂件到前端if (null != workbook) {String excelName = "export-01";String fileName = excelName + System.currentTimeMillis() + ".xlsx";fileName = new String(fileName.getBytes("UTF-8"), "iso8859-1");response.setHeader("Content-Disposition", "attachment;filename=" + fileName); response.setContentType("application/x-download");response.setCharacterEncoding("UTF-8");response.addHeader("Pargam", "no-cache");response.addHeader("Cache-Control", "no-cache");response.flushBuffer();out = response.getOutputStream();workbook.write(out);out.flush();}} catch (Exception e) {logger.warn("写⼊Excel过程出错!错误原因:" + e.getMessage()); } finally {try {if (null != workbook) {workbook.close();}if (null != out) {out.close();}} catch (IOException e) {logger.warn("关闭workbook或outputStream出错!");}}}}。

POI3.10读取Excel模板填充数据后生成新的Excel文件

POI3.10读取Excel模板填充数据后生成新的Excel文件

POI3.10读取Excel模板填充数据后⽣成新的Excel⽂件private final DecimalFormat df = new DecimalFormat("#0.00");public void test(){String filePath = "G:\\tmp\\qhjt_yd.xls";String destPath = "G:\\tmp\\qhjt_yd2.xls";List<Map<String,Double>> list = getData();Map<String,String> nsrxx = getBaseInfo();try {//读取excel模板HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(filePath));//读取第⼀个⼯作簿HSSFSheet sheet = workbook.getSheetAt(0);//设置保留公式sheet.setForceFormulaRecalculation(true);//定义⾏与列HSSFRow row;HSSFCell cell;//第3⾏,第2列row = sheet.getRow(2);cell = row.getCell(1);cell.setCellValue(nsrxx.get("nsrmc"));//第3⾏,第4列row = sheet.getRow(2);cell = row.getCell(3);cell.setCellValue(nsrxx.get("bsq"));//第13⾏,第3列row = sheet.getRow(12);cell = row.getCell(2);cell.setCellValue(nsrxx.get("ycsm"));//第14⾏,第2列row = sheet.getRow(13);cell = row.getCell(1);cell.setCellValue(nsrxx.get("tbr"));//第14⾏,第5列row = sheet.getRow(13);cell = row.getCell(4);cell.setCellValue(nsrxx.get("lxdh"));//从第6⾏开始读取到第12⾏for(int i=5;i<12;i++){Map<String,Double> mm = list.get(i-5);//获取⾏row = sheet.getRow(i);//依次设置3,4列cell = row.getCell(2);cell.setCellValue(df.format(mm.get("bq")));cell = row.getCell(3);cell.setCellValue(df.format(mm.get("tq")));}FileOutputStream out = new FileOutputStream(destPath);workbook.write(out);out.close();} catch (IOException ex) {Logger.getLogger(PoiUtil.class.getName()).log(Level.SEVERE, null, ex);}}。

JAVA用POI从Excel读取数据进行相关统计,JFreeChart绘制图表

JAVA用POI从Excel读取数据进行相关统计,JFreeChart绘制图表

代码大概三百行吧,不多。

本来连接数据库做是个不错的选择,但是我刚刷了系统木有了又懒得装,从txt输入又感觉太low,最后就作死选择了以前从未尝试过的从Excel 输入,并碰到了各种问题_(:зゝ∠)_比如Cannot get a String value from a numeric cell 的异常错误,卡了我好久,直到无语地发现POI操作Excel时会无视Excel里的单元格设置,自判数据类型,所以还要使用setCellType.(*゜ー゜*)实现步骤(1)我用javax.swing.JFileChooser类来显示文件对话框,让用户选择一个Excel文件。

(2)使用Apache POI API从Excel文件中读取数据,对Employee类进行批量初始化。

(3)实现公司员工收入的相关统计,这里我实现了人数统计、最大/最小工龄查找、最大/最小工资查找、男女比例、平均工资、平均年龄、平均工龄等。

(4)建立Dataset。

将你所想要显示的数据都放到这个库中。

(5)建立JFreeChart对象。

将你的dataset填入到这个对象中。

(6)处理Chart中文显示问题(7)设置各种JFreeChart的属性和效果。

通过它提供的各种方法和接口设置相关的属性。

(8)用JFreeChart绘制图表,然后按照个人的需求进行执行。

(9)写界面,以swing形式输出。

测试截图(1)生成消息对话框,要求用户选择一个Excel文件,单击“确定”(2)生成文件选择器,我打开了存放在D盘BUAA文件夹里的Employee.xls补充说明:这是文件Employee.xls的内容(3)进行相关统计,并通过消息对话框显示统计结果(4)询问用户是否生成统计图,如果点“取消”或“否”,运行完毕;如果点是,系统将生成统计图,以员工为横轴,以年龄、工龄、工资三项数值为纵轴。

图表的显示效果会根据窗口大小自适应,改变横纵轴的比例尺。

下面是窗口最大化的效果程序清单1 2 3 4 5 6 7 8public class Employee {String ID;String name;String sex;double age;double workAge;double sal;9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32public void setID(String ID) {this.ID = ID;}public void setName(String name) { = name;}public void setSex(String sex) {this.sex = sex;}public void setAge(double age) {this.age = age;}public void setWorkAge(double workAge) {this.workAge = workAge;}public void setSal(double sal) {this.sal = sal;}}一共有两个:Employee.Java和EmployeeStatic.javaEmployeeStatic.javaimport java.awt.RenderingHints;import java.io.FileInputStream;import java.util.ArrayList;import java.util.List;import javax.swing.JFileChooser;import javax.swing.JOptionPane;//org.apache.poiimport ermodel.HSSFSheet;import ermodel.HSSFWorkbook;import ermodel.Cell;import ermodel.Row;import ermodel.XSSFSheet;import ermodel.XSSFWorkbook;//org.jfreeimport org.jfree.chart.ChartFactory;import org.jfree.chart.ChartFrame;import org.jfree.chart.JFreeChart;import org.jfree.chart.axis.CategoryAxis;import org.jfree.chart.axis.ValueAxis;import org.jfree.chart.plot.CategoryPlot;import org.jfree.chart.plot.PlotOrientation;import org.jfree.chart.title.TextTitle;import org.jfree.data.category.CategoryDataset;import org.jfree.data.category.DefaultCategoryDataset;import java.awt.Font;public class EmployeeStatics {public static void main(String[] args) {// TODO Auto-generated method stubJOptionPane.showMessageDialog(null,"\n您好,我是智能机器人小紫\n\n" + "很高兴为您提供员工数据统计分析服务\n\n"+ "请选择一个Excel文件 ^_^\n\n","选择Excel文件",RMATION_MESSAGE); ArrayList<Employee> Employees = null;//从Excel文件读取数据try {Employees = ReadFileUsingFileChooser();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}//人数统计int n = Employees.size();//最大最小工资、工龄、工资初始化int maxA = 0;int minA = Integer.MAX_VALUE;int maxWA = 0;int minWA = Integer.MAX_VALUE;int maxS = 0;int minS = Integer.MAX_VALUE;//男女性别人数int M = 0;int FM = 0;double sumS, sumA, sumWA, avgS, avgA, avgWA, MFM; sumS = sumA = sumWA = 0;//遍历实现相关统计for (Employee e : Employees) {if(e.age > maxA)maxA = (int) e.age;if(e.age < minA)minA = (int) e.age;if(e.workAge > maxWA)maxWA = (int) e.workAge;if(e.workAge < minWA)minWA = (int) e.workAge;if(e.sal > maxS)maxS = (int) e.sal;if(e.sal < minS)minS = (int) e.sal;sumS += e.sal;sumA += e.age;sumWA += e.workAge;if (e.sex.equals("男"))M++;if (e.sex.equals("女"))FM++;}//计算平均值avgS = sumS / n;avgA = sumA / n;avgWA = sumWA / n;//计算男女比例MFM = (double) M / FM;JOptionPane.showMessageDialog(null,"员工人数为" + n + ",男女比例为" + MFM + "(男/女)\n"+ "平均年龄为" + avgA + ",平均工龄为" + avgWA + ",平均工资为" + avgS + "\n"+ "最高年龄为" + maxA + ",最低年龄为" + minA + ",最高工龄为" + maxWA + ",最低工龄为" + minWA + "\n"+ "最高工资为" + maxS + "K,最低工资为" + minS + "K\n");int option=JOptionPane.YES_OPTION;option=JOptionPane.showConfirmDialog(null, "是否显示员工数据统计图?");if (option==JOptionPane.YES_OPTION) {CategoryDataset dataset = getDataSet(Employees);//构造chartJFreeChart chart = ChartFactory.createBarChart3D("员工数据统计图", // 图表标题"员工属性", // 目录轴的显示标签--横轴"数值", // 数值轴的显示标签--纵轴dataset, // 数据集PlotOrientation.VERTICAL, // 图表方向:水平、true, // 是否显示图例(对于简单的柱状图必须false, // 是否生成工具false// 是否生成URL链接);//处理chart中文显示问题processChart(chart);//chart 以swing形式输出ChartFrame pieFrame = new ChartFrame("员工数据统计图", chart);pieFrame.pack();pieFrame.setVisible(true);}}public static ArrayList<Employee>ReadFileUsingFileChooser()throws Ex ception {// TODO Auto-generated method stubJFileChooser fileChooser = new JFileChooser();ArrayList temp = new ArrayList();if (fileChooser.showOpenDialog(null)==JFileChooser.APPROVE_OPTION) {java.io.File file = fileChooser.getSelectedFile();FileInputStream fileIn = new FileInputStream(file);//根据指定的文件输入流导入Excel从而产生Workbook对象HSSFWorkbook wb0 = new HSSFWorkbook(fileIn);//获取Excel文档中的第一个表单HSSFSheet sht0 = wb0.getSheetAt(0);//对Sheet中的每一行进行迭代int r;int rowNum = sht0.getPhysicalNumberOfRows();for (r = 1; r <= rowNum; r++) {Row row = sht0.getRow(r);if (row == null) {break;}//创建实体类Employee info=new Employee();//取出当前行第1个单元格数据,并封装在info实体stuName属性上row.getCell(0).(Cell.);info.setID(row.getCell(0).getStringCellValue());info.setName(row.getCell(1).getStringCellValue());info.setSex(row.getCell(2).getStringCellValue());info.setAge(row.getCell(3).getNumericCellValue());info.setWorkAge(row.getCell(4).getNumericCellValue());info.setSal(row.getCell(5).getNumericCellValue());temp.add(info);}fileIn.close();}else {System.out.println("No file selected");}return temp;}//获取一个演示用的组合数据集对象private static CategoryDatasetgetDataSet(ArrayList<Employee> Employe es) {DefaultCategoryDataset dataset = new DefaultCategoryDataset();for (Employee e : Employees){dataset.addValue(e.workAge, "工龄", );dataset.addValue(e.sal, "工资", );dataset.addValue(e.age, "年龄", );}return dataset;}//解决图表汉字显示问题private static void processChart(JFreeChart chart) {CategoryPlot plot = chart.getCategoryPlot();CategoryAxis domainAxis = plot.getDomainAxis();ValueAxis rAxis = plot.getRangeAxis();chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASI NG,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);TextTitle textTitle = chart.getTitle();textTitle.setFont(new Font("宋体", Font.PLAIN, 20));domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));rAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));rAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));chart.getLegend().setItemFont(new Font("宋体", Font.PLAIN, 12));// renderer.setItemLabelGenerator(newLabelGenerator(0.0));// renderer.setItemLabelFont(newFont("宋体", Font.PLAIN, 12));//renderer.setItemLabelsVisible(true);}}Employee.javapublic class Employee {String ID;String name;String sex;double age;double workAge;double sal;public void setID(String ID) {this.ID = ID;}public void setName(String name) { = name;}public void setSex(String sex) {this.sex = sex;}public void setAge(double age) {this.age = age;}public void setWorkAge(double workAge) { this.workAge = workAge;}public void setSal(double sal) {this.sal = sal;}}。

POI解析excel2007和生成excel2007

POI解析excel2007和生成excel2007

最近几天在整理客户的数据,数据量比较大,有几十万条,用到了excel。

用户提供的数据有很多重复的,这个我们要挑拣出来,我用代码写挑拣重复的数据,原来用jxl解析excel,发现excel不支持office2007,并且excel2003最大的行数只能是65535,这样就不能运行一次代码解决问题了。

查了下资料,apache 的POI可以解析office2007。

下面两个简单例子望能提供给网友参考。

1.读取excel2007Java代码1. //office2007工作区2. XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream("D:/temp/test_poi.xlsx"));3. //获得该工作区的第一个sheet4. XSSFSheet sheet = wb.getSheetAt(0);5. //总共有多少行,从0开始6. int totalRows = sheet.getLastRowNum();7. for (int i = 0; i <= totalRows; i++) {8. //取得该行9. XSSFRow row = sheet.getRow(i);10. //注释的代码,是为了防止excel文件有空行11.// if(row == null) {12.// continue;13.// }14. System.out.println(row.getCell(1).toString());15. }2.生成excel2007Java代码1.//输出流2.OutputStream os = new FileOutputStream("D:/temp/create.xlsx");3.//工作区4.XSSFWorkbook wb = new XSSFWorkbook();5.//创建第一个sheet6.XSSFSheet sheet= wb.createSheet("test");7.//生成第一行8.XSSFRow row = sheet.createRow(0);9.//给这一行的第一列赋值10.row.createCell(0).setCellValue("column1");11.//给这一行的第一列赋值12.row.createCell(1).setCellValue("column2");13.//写文件14.wb.write(os);15.//关闭输出流16.os.close();。

JAVA使用POI(XSSFWORKBOOK)读取EXCEL文件过程解析

JAVA使用POI(XSSFWORKBOOK)读取EXCEL文件过程解析

JAVA使⽤POI(XSSFWORKBOOK)读取EXCEL⽂件过程解析经过⼀番搜索发现,java操纵excel⽂件常⽤的有jxl和poi两种⽅式,孰好孰坏看⾃⼰需求⽽定。

其中最主要的区别在于jxl不⽀持.xlsx,⽽poi⽀持.xlsx这⾥介绍的使⽤poi⽅式(XSSFWorkbook),实际上poi提供了HSSFWorkbook和XSSFWorkbook两个实现类。

区别在于HSSFWorkbook是针对.xls⽂件,XSSFWorkbook是针对.xslx⽂件。

⾸先明确⼀下基本概念: 先创建⼀个⼯作簿,⼀个⼯作簿可以有多个⼯作表,⼀个⼯作表可以有多个⾏,⼀个⾏可以有多个单元格 ⼯作簿 >>>>>>>>XSSFWorkbook ⼯作表 >>>>>>>>XSSFSheet ⾏ >>>>>>>>XSSFRow 单元格 >>>>>>>>XSSFCell下图为创建的student.xlsx的内容:读取student.xlsx⽂件代码:package com.zjk.testexcel;import ermodel.*;import java.io.FileInputStream;import java.io.IOException;/*** @Auther: zjk* @Date: 2019/8/30* @Description:*/public class TestExcel1 {public static void main(String[] args) {try {//创建⼯作簿XSSFWorkbook xssfWorkbook = new XSSFWorkbook(new FileInputStream("D:\\test-excel\\student.xlsx"));System.out.println("xssfWorkbook对象:" + xssfWorkbook);//读取第⼀个⼯作表(这⾥的下标与list⼀样的,从0开始取,之后的也是如此)XSSFSheet sheet = xssfWorkbook.getSheetAt(0);System.out.println("sheet对象:" + sheet);//获取第⼀⾏的数据XSSFRow row = sheet.getRow(0);System.out.println("row对象:" + row);//获取该⾏第⼀个单元格的数据XSSFCell cell0 = row.getCell(0);System.out.println("cello对象:" + cell0);} catch (IOException e) {e.printStackTrace();}}}控制台输出结果:可以发现具体到⾏对象时,就解析成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/spreadsheetDrawing" xmlns:x14="/office/spre <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,即总⾏数。

NPOI读写Excel

NPOI读写Excel

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

Java开发小技巧(六):使用ApachePOI读取Excel

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程序⼀般是分层设计的,⽽不同的层可能是不同的开发⼈员来完成,这样就很容易出现不同的层重复进⾏数据验证逻辑,导致代码冗余等问题。

Javapoi读取,写入Excel,处理row和cell可能为空的情况

Javapoi读取,写入Excel,处理row和cell可能为空的情况

Javapoi读取,写⼊Excel,处理row和cell可能为空的情况⾸先需要导⼊包import ermodel.HSSFWorkbook;import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;import ermodel.Row;import ermodel.Sheet;import ermodel.Workbook;然后写⽅法,由于我使⽤的框架全部是spring此处我只写⼊实现层和控制层代码@Overridepublic InputStream loadMatComYearPlanXls(String MAT_NO_, String MAT_DESC_, Integer MAT_TYPE_, String MAT_SPEC_CAT_CODE_, String COM_CODE_, String DEPT_CODE_, Integer YEAR_, Integer MONTH_, String MAT_BUDGE NPOIFSFileSystem fs = null;Workbook workbook = null;ByteArrayOutputStream baos = new ByteArrayOutputStream();try {File file = new File(this.getClass().getResource("/../../resource/matComYearPlan.xls").getFile());FileInputStream inputStream = new FileInputStream(file);fs = new NPOIFSFileSystem(inputStream);workbook = (Workbook) new HSSFWorkbook(fs.getRoot(), true);Sheet sheet = workbook.getSheetAt(0);List<Map<String, Object>> matYearPlanList = selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BA List<Map<String, Object>> matTypedmCodeList = dmCodeService.selectDmCodeByGroupName("MAT_TYPE_", operator);List<Map<String, Object>> processStatusTypedmCodeList = dmCodeService.selectDmCodeByGroupName("PROCESS_STATUS_TYPE_", operator);List<Map<String, Object>> matBudgetCatList = matBudgetCatService.selectMatBudgetCat(1, -1, operator);List<Map<String, Object>> matSpecCatList = matSpecCatService.selectMatSpecCat(1, -1, operator);Map<String, Object> matYearPlan;String MAT_BUDGET_CAT_NAME_ = "";String PARENT_MAT_BUDGET_CAT_ID_;for (int i = 0; i < matYearPlanList.size(); i++) {matYearPlan = matYearPlanList.get(i);Row row = sheet.createRow(i + 1);row.createCell(0).setCellValue((String) matYearPlan.get("MAT_NO_"));row.createCell(1).setCellValue((String) matYearPlan.get("MAT_DESC_"));row.createCell(2).setCellValue((String) matYearPlan.get("LARGE_MAT_CAT_CODE_"));row.createCell(3).setCellValue((String) matYearPlan.get("UNIT_"));if (matYearPlan.get("PLANNED_PRICE_") != null) {row.createCell(4).setCellValue(((BigDecimal) matYearPlan.get("PLANNED_PRICE_")).doubleValue());}if (matYearPlan.get("AMOUNT_") != null) {row.createCell(5).setCellValue(((BigDecimal) matYearPlan.get("AMOUNT_")).doubleValue());}if (matYearPlan.get("PLANNED_PRICE_") != null && matYearPlan.get("AMOUNT_") != null) {row.createCell(6).setCellValue(((BigDecimal) matYearPlan.get("PLANNED_PRICE_")).doubleValue() * ((BigDecimal) matYearPlan.get("AMOUNT_")).doubleValue());}if (matYearPlan.get("MAT_TYPE_") != null) {for (int j = 0; j < matTypedmCodeList.size(); j++) {Map<String, Object> matTypedmCode = matTypedmCodeList.get(j);if ((((BigDecimal) matYearPlan.get("MAT_TYPE_")).intValue()) == (((BigDecimal) matTypedmCode.get("CODE_"))).intValue()) {row.createCell(7).setCellValue((String) matTypedmCode.get("VALUE_"));break;}}}row.createCell(8).setCellValue((String) matYearPlan.get("DEPT_NAME_"));for (int j = 0; j < matBudgetCatList.size(); j++) {Map<String, Object> matBudgetCat = matBudgetCatList.get(j);if (((String) matYearPlan.get("MAT_BUDGET_CAT_ID_")).equals((String) matBudgetCat.get("MAT_BUDGET_CAT_ID_"))) {MAT_BUDGET_CAT_NAME_ = (String) matBudgetCat.get("MAT_BUDGET_CAT_NAME_");PARENT_MAT_BUDGET_CAT_ID_ = (String) matBudgetCat.get("PARENT_MAT_BUDGET_CAT_ID_");while (PARENT_MAT_BUDGET_CAT_ID_ != null) {for (int k = 0; k < matBudgetCatList.size(); k++) {matBudgetCat = matBudgetCatList.get(k);if (PARENT_MAT_BUDGET_CAT_ID_.equals((String) matBudgetCat.get("MAT_BUDGET_CAT_ID_"))) {MAT_BUDGET_CAT_NAME_ = (String) matBudgetCat.get("MAT_BUDGET_CAT_NAME_") + "/" + MAT_BUDGET_CAT_NAME_;PARENT_MAT_BUDGET_CAT_ID_ = (String) matBudgetCat.get("PARENT_MAT_BUDGET_CAT_ID_");break;}}}row.createCell(9).setCellValue("/" + MAT_BUDGET_CAT_NAME_ + "/");break;}}if (matYearPlan.get("MAT_SPEC_CAT_CODE_") != null) {for (int j = 0; j < matSpecCatList.size(); j++) {Map<String, Object> matSpecCat = matSpecCatList.get(j);if (((String) matYearPlan.get("MAT_SPEC_CAT_CODE_")).equals((String) matSpecCat.get("CODE_"))) {row.createCell(10).setCellValue((String) matSpecCat.get("VALUE_"));break;}}}if (matYearPlan.get("PROCESS_STATUS_") != null) {for (int j = 0; j < processStatusTypedmCodeList.size(); j++) {Map<String, Object> processStatusTypedmCode = processStatusTypedmCodeList.get(j);if ((((BigDecimal) matYearPlan.get("PROCESS_STATUS_")).intValue()) == (((BigDecimal) processStatusTypedmCode.get("CODE_")).intValue())) {row.createCell(11).setCellValue((String) processStatusTypedmCode.get("VALUE_"));break;}}}}workbook.write(baos);baos.flush();byte[] bytes = baos.toByteArray();return new ByteArrayInputStream(bytes, 0, bytes.length);}catch (Exception e) {e.printStackTrace();return null;}finally {try {fs.close();workbook.close();baos.close();}catch (IOException e) {}}}其中有个selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_,MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, 1, -1, operator);⽅法是我的业务⽅法,可根据需要改变⾃⼰实际的参数,对⾃⼰的代码进⾏修改Row row = sheet.createRow(i + 1);row.createCell(0).setCellValue((String) matYearPlan.get("MAT_NO_"));这两句代码是与其他⼈不同的地⽅,有些⼈的代码是getRow(),getCell()。

java使用poi读取ppt文件和poi读取excel、word示例

java使用poi读取ppt文件和poi读取excel、word示例

java使⽤poi读取ppt⽂件和poi读取excel、word⽰例Apache的POI项⽬可以⽤来处理MS Office⽂档,codeplex上还有⼀个它的.net版本。

POI项⽬可创建和维护操作各种基于OOXML和OLE2⽂件格式的Java API。

⼤多数MS Office都是OLE2格式的。

POI通HSMF⼦项⽬来⽀持Outlook,通过HDGF⼦项⽬来⽀持Visio,通过HPBF⼦项⽬来⽀持Publisher。

使⽤POI抽取Word简单⽰例:要引⼊poi-3.7.jat和poi-scratchpad-3.7.ajr这两个包。

复制代码代码如下:package msoffice;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import org.apache.poi.hwpf.HWPFDocument;import org.apache.poi.hwpf.extractor.WordExtractor;import ermodel.CharacterRun;import ermodel.Paragraph;import ermodel.Range;import ermodel.Section;public class Word {// 直接抽取全部内容public static String readDoc1(InputStream is) throws IOException {WordExtractor extractor = new WordExtractor(is);return extractor.getText();}//分章节Section、段落Paragraph、字符串CharacterRun抽取public static void readDoc2(InputStream is) throws IOException {HWPFDocument doc=new HWPFDocument(is);Range r=doc.getRange();for(int x=0;x<r.numSections();x++){Section s=r.getSection(x);for(int y=0;y<s.numParagraphs();y++){Paragraph p=s.getParagraph(y);for(int z=0;z<p.numCharacterRuns();z++){CharacterRun run=p.getCharacterRun(z);String text=run.text();System.out.print(text);}}}}public static void main(String[] args) {File file = new File("/home/orisun/1.doc");try {FileInputStream fin = new FileInputStream(file);String cont = readDoc1(fin);System.out.println(cont);fin.close();fin = new FileInputStream(file);readDoc2(fin);fin.close();} catch (IOException e) {e.printStackTrace();}}}POI抽取PPT⽰例:复制代码代码如下:package msoffice;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import org.apache.poi.hslf.HSLFSlideShow;import org.apache.poi.hslf.extractor.PowerPointExtractor;import org.apache.poi.hslf.model.Slide;import org.apache.poi.hslf.model.TextRun;import ermodel.SlideShow;public class PPT {//直接抽取幻灯⽚的全部内容public static String readDoc1(InputStream is) throws IOException{ PowerPointExtractor extractor=new PowerPointExtractor(is);return extractor.getText();}//⼀张幻灯⽚⼀张幻灯⽚地读取public static void readDoc2(InputStream is) throws IOException{ SlideShow ss=new SlideShow(new HSLFSlideShow(is));Slide[] slides=ss.getSlides();for(int i=0;i<slides.length;i++){//读取⼀张幻灯⽚的标题String title=slides[i].getTitle();System.out.println("标题:"+title);//读取⼀张幻灯⽚的内容(包括标题)TextRun[] runs=slides[i].getTextRuns();for(int j=0;j<runs.length;j++){System.out.println(runs[j].getText());}}}public static void main(String[] args){File file = new File("/home/orisun/2.ppt");try{FileInputStream fin=new FileInputStream(file);String cont=readDoc1(fin);System.out.println(cont);fin.close();fin=new FileInputStream(file);readDoc2(fin);fin.close();}catch(IOException e){e.printStackTrace();}}}Excel⽂件由多个Workbook组成,⼀个Workbook由多个Sheet组成。

Springboot之使用POI读取解析Excel文件

Springboot之使用POI读取解析Excel文件

Springboot之使⽤POI读取解析Excel⽂件1、引⼊依赖jar包。

在pom.xml中引⼊两个依赖的包即可:<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>RELEASE</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>RELEASE</version></dependency>2、读取xxx.xlsx@GetMapping(value = "/impPriceRecord")public InvokeResult impPriceRecord() throws Exception {try {List<AmoycarClue> infos = new ArrayList<AmoycarClue>();InputStream is = new FileInputStream("D:/xxx.xlsx");XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);XSSFRow titleCell = xssfSheet.getRow(0);for (int i = 1; i <= xssfSheet.getLastRowNum(); i++) {XSSFRow xssfRow = xssfSheet.getRow(i);int minCell = xssfRow.getFirstCellNum();int maxCell = xssfRow.getLastCellNum();XSSFCell bidCode = xssfRow.getCell(0);XSSFCell owerName = xssfRow.getCell(1);XSSFCell ownersex = xssfRow.getCell(2);XSSFCell owerMobile = xssfRow.getCell(3);XSSFCell basePrice = xssfRow.getCell(4);XSSFCell bidType = xssfRow.getCell(5);XSSFCell bidDealerId = xssfRow.getCell(6);XSSFCell bidDealerName = xssfRow.getCell(7);XSSFCell bidName = xssfRow.getCell(8);XSSFCell bidMobile = xssfRow.getCell(9);XSSFCell carNumber = xssfRow.getCell(10);XSSFCell autoNumber = xssfRow.getCell(11);XSSFCell carUnifiedNumber = xssfRow.getCell(12);XSSFCell curBid = xssfRow.getCell(13);XSSFCell bidStatus = xssfRow.getCell(14);XSSFCell maxBid = xssfRow.getCell(15);XSSFCell priceGap = xssfRow.getCell(16);XSSFCell bidCreateTime = xssfRow.getCell(17);XSSFCell expectPrice = xssfRow.getCell(18);XSSFCell roundStatus = xssfRow.getCell(19);AmoycarClue model = new AmoycarClue();model.setBidCode(getValue(bidCode));model.setBizoppCode("");model.setOriginalCode("");model.setWorkNo("");model.setOwnerName(getValue(owerName) + "");model.setOwnerSex(Double.valueOf(getValue(ownersex)).intValue());model.setOwnerMobile(getValue(owerMobile));model.setBasePrice(Double.valueOf(getValue(basePrice)));model.setBidName(getValue(bidName));model.setBidMobile(getValue(bidMobile));model.setBidType(Double.valueOf(getValue(bidType)).intValue());model.setCarCode(code);model.setMaxBid(Double.valueOf(getValue(maxBid)));model.setCurBid(Double.valueOf(getValue(curBid)));model.setPriceGap((Double.valueOf(getValue(priceGap))));model.setBidStatus(Double.valueOf(getValue(bidStatus)).intValue());SimpleDateFormat pat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");if (bidCreateTime!= null) {try {String sDate=getValue(bidCreateTime);java.util.Date uDate = pat.parse(sDate);model.setBidCreatetime(uDate);} catch (ParseException ex) {ex.printStackTrace();}}model.setRoundStatus(Double.valueOf(getValue(roundStatus)).intValue());model.setExpectPrice(Double.parseDouble(getValue(expectPrice)));model.setBidDealerId(getValue(bidDealerId));model.setBidDealerName(getValue(bidDealerName));try {auctionClient.syncAmoycarClue(model);Thread.sleep(1000);} catch (Exception ex) {ex.printStackTrace();return InvokeResult.failure(500, "impPriceRecord:插⼊错误BidCode:{" + model.getBidCode() +"}"+ ex.getMessage());}}return InvokeResult.success(true);} catch (Exception e) {return InvokeResult.failure(500,"impPriceRecord:历史数据导⼊错误"+e.getMessage());}}3、格式⽅法private String getValue(XSSFCell xssfRow) {if (xssfRow != null) {// if (xssfRow != null) {// xssfRow.setCellType(xssfRow.CELL_TYPE_STRING);// }if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) {return String.valueOf(xssfRow.getBooleanCellValue());} else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) {String result = "";if (xssfRow.getCellStyle().getDataFormat() == 22) {// 处理⾃定义⽇期格式:m⽉d⽇(通过判断单元格的格式id解决,id的值是58)SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");double value = xssfRow.getNumericCellValue();Date date = ermodel.DateUtil.getJavaDate(value);result = sdf.format(date);} else {double value = xssfRow.getNumericCellValue();CellStyle style = xssfRow.getCellStyle();DecimalFormat format = new DecimalFormat();String temp = style.getDataFormatString();// 单元格设置成常规if (temp.equals("General")) {format.applyPattern("#");}result = format.format(value);}return result;} else {return String.valueOf(xssfRow.getStringCellValue());}} elsereturn "0";}Java操作Excel中XSSFCell.CELL_TYPE_BOOLEAN、BOOLEAN、NUMERIC⽆定义解决⽅法错误原因:jar包版本更新,官⽅改动;解决⽅法:导⼊CellType包import ermodel.CellType使⽤CellType.BOOLEAN代替XSSFCell.CELL_TYPE_BOOLEAN使⽤CellType.NUMBERIC代替XSSFCell.CELL_TYPE_NUMBERIC。

POI实现excel的数据验证

POI实现excel的数据验证

POI实现excel的数据验证⽬录前⾔Apache POI是Apache软件基⾦会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

实际开发中,⽤POI来读写excel⽂档的⽐较多。

所以,这⾥记录下⽤POI读取excel⽂档的⼀些难点做下记录。

难点1:合并单元格在实际开发中,有时会遇到如图⽰例,需要按照如图所⽰进⾏导出excel⽂件。

这就涉及到了合并单元格和给单元格赋值的问题。

代码实现策略:step 1: 合并单元格eventSheet.addMergedRegion(new CellRangeAddress(lineNum, fields.size() + lineNum - 1, 1, 1));step 2: 给单元格赋值按照正常给单元格赋值即可,只是在合并的单元格第⼀⾏赋值就⾏,不⽤重复赋值;cell = row.createCell((short) 1);cell.setCellValue(eventVO.getEventId());cell.setCellStyle(align_center_style);难点2:数据验证-下拉框在导出excel⽂件时,需要添加数据验证的下拉框。

如图:代码实现策略:step 1:设置需要进⾏数据验证的单元格范围和可供选择的值/*** 设置 excel数据验证** @param firstRow* @param firstCol* @param endRow* @param endCol* @param strList 可供选择的值* @return* @since @ 2018年3⽉14⽇*/XSSFDataValidation getDataValidationList(XSSFSheet sheet, short firstRow, short firstCol, short endRow, short endCol, List<String> strList) {String[] datas = strList.toArray(new String[0]);XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createExplicitListConstraint(datas);CellRangeAddressList addressList = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);XSSFDataValidation validation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, addressList);return validation;}step 2:给当前sheet添加数据验证sheet.addValidationData(line2ValidationList);难点3:数据验证-某列保证唯⼀性有时候在excel⽂件的某列添加数据时,需要保证某列的数据唯⼀。

java poi excel 读写

java poi excel 读写

题目:探索Java中POI库的Excel读写功能1. 简介Java作为一种广泛应用的编程语言,拥有丰富的库和框架来支持各种应用场景。

其中,POI(Poor Obfuscation Implementation)库是Java操作Microsoft Office格式文件的重要工具之一。

在POI库中,Excel的读写功能一直备受开发者关注,因为Excel在商业和数据处理领域有着广泛的应用。

本文将深入探讨Java中POI库的Excel读写功能,介绍其基本用法和注意事项。

2. POI库的基本概念POI库是Apache软件基金会的一个开源项目,旨在提供Java程序对Microsoft Office格式文件的读写功能。

它支持对Excel、Word和PowerPoint等文件的操作,其中Excel的读写功能是开发者们最为关注的部分。

POI库主要由HSSF(Horrible Spreadsheet Format)、XSSF(XML Spreadsheet Format)和SXSSF(Streaming Usermodel API)三个子项目组成,在具体应用时,开发者可以根据自己的需求选择合适的子项目来实现对Excel文件的读写。

3. Excel的读操作在POI库中,读取Excel文件的操作主要通过HSSFWorkbook和XSSFWorkbook来实现。

HSSFWorkbook用于操作.xls格式的文件,而XSSFWorkbook用于操作.xlsx格式的文件。

使用POI库读取Excel文件的过程包括打开Excel文件、读取工作表、遍历行和列数据等步骤。

在具体的代码实现中,开发者可以根据需求选择不同的API来完成特定的读取任务,例如使用HSSF类库来从.xls文件中读取数据,或者使用XSSF类库来从.xlsx文件中读取数据。

在读取Excel文件时,开发者需要注意文件格式、数据类型和异常处理等问题,以确保读取的准确性和健壮性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java-Excel 报表开发 POI(2009-02-19 21:44:10)转载▼分类:java标签:java杂谈开发环境为windowsXP-SP2,Eclipse3.2,JDK1.5.07,其实差不多都行,不会有太大的差异。

本文从POI 下载开始讲解,前提是开发环境包括系统变量等等已经正确设置完毕。

1.POI的下载截至本文发表,POI最新版本是3.0.1,距离上一个Final版本有3年了吧,以至于我差点儿就把他放弃了——以为没人管了。

官方的公告讲,这一版主要是追加了一些新的特性和BUG修正,不过稍微有点儿遗憾的是,还不能很好的操作Excel2007。

POI官方网址:/JAR包下载:/poi/release/bin/poi-bin-3.0.1-FINAL-20070705.zip源码下载:/poi/release/src/poi-src-3.0.1-FINAL-20070705.zip下载上面的JAR和源码(源码不是必须的,但是为了早日修得正果,深入系统的看看POI代码还是有必要的)并解压待用。

2.用Eclipse搭建项目打开Eclipse依次点击File->New->Java Project输入项目名称,本例中设置为POI单击完成在项目上点击右键->New->Folder输入文件夹名称lib把刚才解压的poi-3.0.1-FINAL-20070705.jar复制过来右键点击项目,选择Properties在左侧列表里选中Java Build Path,右侧选中Libraries点击Add JARs,选择POI项目的lib下的所有文件两次OK确认,回到Eclipse界面小技巧,快捷操作:可以用鼠标左键选中poi-3.0.1-FINAL-20070705.jar但不松开,拖到任务栏的Eclipse 图标上等候1秒左右,Eclipse会自动弹起来,依然不松开移动到lib文件夹上,这个时候鼠标后面跟个十字符号,松开左键,就完成了复制动作。

这个是对整个windows系统都好用的快捷复制方式,视源盘符和目标盘符的不同偶尔会用到Ctrl键。

到此为止,我们做好了POI学习的前提准备,接下来将从最简单的文档创建开始一步一步学习怎样让POI 更好的为我们工作。

第一讲:基本的Excel读写本文主要演示一下POI的基本操作,例如怎样读取和创建一个具体的Excel文件。

按照惯例,拿HelloWorld 说事儿。

说明:本文主要内容皆包含于官方帮助手册,之所以要拿出来,出于两个原因,手册是英文的+手册是对应2.5.1的。

核心代码如下,注释部分为讲解。

这里只挑干的讲,完整的代码请参考(下载代码)。

//创建一个空白的WorkBookHSSFWorkbook wb = new HSSFWorkbook();//基于上面的WorkBook创建属于此WorkBook的Sheet,//3.0.1版在使用全角Sheet名的时候不必再setEncdoing了,个人感觉方便了许多。

HSSFSheet st = wb.createSheet("测试页");//创建属于上面Sheet的Row,参数0可以是0~65535之间的任何一个,//注意,尽管参数是Int类型,但是Excel最多支持65536行HSSFRow row = st.createRow(0);//创建属于上面Row的Cell,参数0可以是0~255之间的任何一个,//同样,是因为Excel最大支持的列数为256列HSSFCell cell = row.createCell((short) 0);//设置此单元格的格式为文本,此句可以省略,Excel会自动识别。

//其他还有几种常用的格式,请参考本文底部的补充部分。

cell.setCellType(HSSFCell.CELL_TYPE_STRING);//此处是3.0.1版的改进之处,上一版可以直接setCellValue("Hello, World!"),//但是在3.0.1里,被deprecated了。

cell.setCellValue(new HSSFRichTextString("Hello, World!"));//创建一个文件输出流,指定到C盘根目录下(C盘都有吧?)//xls是Excel97-2003的标准扩展名,2007是xlsx,目前的POI能直接生产的还是xls格式,//如果此处把扩展名改成xlsx,在用Excel2007打开此文件时会报错。

FileOutputStream writeFile = new FileOutputStream("c:/helloworld.xls");//把WorkBook写到流里wb.write(writeFile);//记得手动关闭流,官方文档已经做了特别说明,说POI不负责关闭用户打开的流。

所以...writeFile.close();上面就是创建一个新文档的简易代码,下面的例子是读取刚才创建的Excel并把读取到的内容显示在控制台上。

//指定要读取的文件,本例使用上面生成的helloworld.xlsFileInputStream readFile = new FileInputStream("c:/helloworld.xls");//创建一个WorkBook,从指定的文件流中创建,即上面指定了的文件流HSSFWorkbook wb = new HSSFWorkbook(readFile);//获取名称为“测试页”的sheet//注意,如果不能确定具体的名称,可以用getSheetAt(int)方法取得SheetHSSFSheet st = wb.getSheet("测试页");//获得第一行,同上,如果此行没有被创建过则抛出异常HSSFRow row = st.getRow(0);//获取第一个单元格,如果没有被创建过则抛出异常HSSFCell cell = row.getCell((short) 0);//把cell中的内容按字符串方式读取出来,并显示在控制台上//注意,getRichStringCellValue()方法是3.0.1新追加的,//老版本中的getStringCellValue()方法被deprecated了System.out.println(cell.getRichStringCellValue());//记得关闭流readFile.close();上面对创建和读取分别举例说明,回顾两段代码,不难看出POI操作Excel的“套路”:获得一个WorkBook(准确说是HSSFWorkBook,对于POI来说,WorkBook是“另有其类”,以下类同)获得要读/写的Sheet对象获得要操作的Row对象获得最小单位——Cell对象然后就可以随意的读取、写入了。

--------------------------------------------------------------------------------关于单元格格式的补充:单元格一共有如下几种格式,都是HSSFCell类的静态共有属性,CELL_TYPE_NUMERIC - 数字格式CELL_TYPE_STRING - 字符串(默认)CELL_TYPE_FORMULA - 公式CELL_TYPE_BLANK - 空白CELL_TYPE_BOOLEAN - 布尔CELL_TYPE_ERROR - 错误第二讲:单元格边框、字体及颜色此文概要性的讲述了一下单元格的边框、字体以及颜色的设置方式,在POI中,这一切都是通过实例化HSSFCellStyle对象来实现的,HSSFCellStyle类还有很多其他实际有用方法,本例中只是取平时用的比较普遍的一些设置来做演示的。

好,开始讲解了……// 设置行号row.setHeightInPoints((short) 50);// 设置列宽,(256 * 50)这种写法是因为width参数单位是单个字符的256分之一st.setColumnWidth(cell.getCellNum(), (short) (256 * 50));// 让HSSFWorkbook创建一个单元格样式的对象// 小技巧:在多处用到完全一样的样式的时候可以用工厂模式生产HSSFCellStyle cellStyle = wb.createCellStyle();// 设置单元格的横向和纵向对齐方式,具体参数就不列了,参考HSSFCellStylecellStyle.setAlignment(HSSFCellStyle.ALIGN_JUSTIFY);cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 这个地方是用来在单元格里画斜线的// 原理是在指定的两个点之间画线,然后默认情况此线会随着单元格的变化而变化// 类似Excel那种设置边框的方式达到的斜线效果目前好像POI不支持// 如果是我疏忽了请记得告诉我一些,先行谢过啦HSSFPatriarch patriarch = st.createDrawingPatriarch();HSSFClientAnchor anchor = new HSSFClientAnchor();anchor.setAnchor(cell.getCellNum(), row.getRowNum(), 0, 0, (short) (cell.getCellNum() + 1),row.getRowNum() + 1, 0, 0);patriarch.createSimpleShape(anchor);// 设置单元格的文本方式为可多行编写方式cellStyle.setWrapText(true);// 设置单元格的填充方式,以及前景颜色和背景颜色// 三点注意:// 1.如果需要前景颜色或背景颜色,一定要指定填充方式,两者顺序无所谓;// 2.如果同时存在前景颜色和背景颜色,前景颜色的设置要写在前面;// 3.前景颜色不是字体颜色。

cellStyle.setFillPattern(HSSFCellStyle.DIAMONDS);cellStyle.setFillForegroundColor(HSSFColor.RED.index);cellStyle.setFillBackgroundColor(HSSFColor.LIGHT_YELLOW.index);// 设置单元格底部的边框及其样式和颜色// 这里仅设置了底边边框,左边框、右边框和顶边框同理可设cellStyle.setBorderBottom(HSSFCellStyle.BORDER_SLANTED_DASH_DOT);cellStyle.setBottomBorderColor(HSSFColor.DARK_RED.index);// 创建一个字体对象,因为字体也是单元格格式的一部分,所以从属于HSSFCellStyle// 下面几个字体的相关设置望文生义,就不用一一说明了吧HSSFFont font = wb.createFont();font.setFontName("宋体");font.setItalic(true);font.setColor(HSSFColor.BLUE.index);font.setFontHeightInPoints((short) 20);font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 将字体对象赋值给单元格样式对象cellStyle.setFont(font);// 将单元格样式对应应用于单元格cell.setCellStyle(cellStyle);这样就OK了,可以可以看到效果了。

相关文档
最新文档