poi读写excel案例
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文件(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模板并修改模板内容与动态的增加⾏ 有时候我们可能遇到相当复杂的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(详细解读)目前处理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 例子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)(四)⼀般在公司写项⽬,写⼊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⽂件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绘制图表
代码大概三百行吧,不多。
本来连接数据库做是个不错的选择,但是我刚刷了系统木有了又懒得装,从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
最近几天在整理客户的数据,数据量比较大,有几十万条,用到了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操纵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,即总⾏数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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了,可以可以看到效果了。