Java POI(第一讲):POI中HSSF用法大全

2023-12-21 18:58
文章标签 java 用法 大全 第一 poi hssf

本文主要是介绍Java POI(第一讲):POI中HSSF用法大全,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Java POI(第一讲):POI中HSSF用法大全

zangyanan2016 3人评论 16128人阅读 2016-08-12 11:38:23

在讲导入Excel功能之前,先拓展一下Excel与POI对应关系:

        表关系

ExcelPOI
Sheet1表0表
Sheet2表1表
Sheet3表2表
依次类推  

        行关系

ExcelPOI
1行0行
2行1行
3行2行
依次类推 

        列关系

ExcelPOI
A列0列
B列1列
C列2列
依次类推 

Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“可怜的模糊实现”。

Apache POI 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。Apache POI 提供Java操作Excel解决方案(适用于Excel97-2008)。

主要组件:

Excel (SS=HSSF+XSSF)

Word (HWPF+XWPF)

PowerPoint (HSLF+XSLF)

OpenXML4J (OOXML)

OLE2 Filesystem (POIFS)

OLE2 Document Props (HPSF)

Outlook (HSMF)

Visio (HDGF)

Publisher (HPBF)

Excel表格有两种格式,一种是xls格式的,另一种是xlsx格式的,相对应的java poi针对操作这两种格式的表格设计了两种不同的组件,目前很多系统中仍然存在HSSF处理xls的代码,此篇文章就是让读者了解HSSF大部分用法,我们会用HSSF制作一个精美的xls格式课程表。

实例一

import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createBlankExcel {public static void main(String[] args) {try {HSSFWorkbook workbook=new HSSFWorkbook();FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();} catch (Exception e) {e.printStackTrace();}}
}

wKiom1esHHmhB9xcAAAU8w6LdpU636.png空白的xls表格。

实例二 单元格赋值

让我们来创建表格并且为表格赋值,关于创建表格,你只要记住HSSFWorkbook 创建HSSFSheet,HSSFSheet创建HSSFRow,HSSFRow创建HSSFCell。

import java.io.FileOutputStream;
import java.util.Random;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createSimpleExcel {public static void main(String[] args) {try {HSSFWorkbook workbook=new HSSFWorkbook();/*** createSheet存在有参和无参两种形式,主要设置sheet名字*/HSSFSheet sheet=workbook.createSheet("课程表");HSSFRow row=sheet.createRow(0);//创建第一行/*** 我们知道课程表第一行是代表周一到周五,下面我们用两种方式创建Cell* 一种用变量,另一种未用变量,用变量的好处后面可以体会到。*/HSSFCell cell=row.createCell(0);cell.setCellValue("星期一");row.createCell(1).setCellValue("星期二");row.createCell(2).setCellValue("星期三");row.createCell(3).setCellValue("星期四");row.createCell(4).setCellValue("星期五");/*** 上面我们只是设置了首行,后面课程我们用同样的方法设置,* 这里面我们用循环方法设置课程*/Random random=new Random();String[] course={"语文","数学","英语","物理","化学","政治","历史","音乐","美术","体育"};//循环产生7行rowfor(int j=1;j<=7;j++){//每个row的1-5个cell设置值,我用随机取数组来写值。HSSFRow row_j=sheet.createRow(j);for(int k=0;k<=4;k++){int i=random.nextInt(10);row_j.createCell(k).setCellValue(course[i]);}}FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();} catch (Exception e) {e.printStackTrace();}}
}

如图:

wKiom1esK1GSF52AAAAerxlBQao531.png

上面代码主要用到了HSSFCell的setCellValue方法,该方法目前有6种不同参数的调用,下面我们来解析一下:

 

setCellValue(boolean)设置boolean型,即true|false
setCellValue(Canlendar)设置Canlendar,Java表示时间的一种类
setCellValue(Date)Date 也是一种时间类型
setCellValue(double)双浮点类型数字
setCellValue(RichTextString)POI中HSSFRichTextString接口的实现类,可以使用不同格式格式化一个单元格的内容。
setCellValue(String)设置字符串

后面我们会继续用到以上不同参数的方法,现在只要了解就好。

实例三 合并单元格

我们继续完善课程表,我们知道每个课程表都有一个名称在第一列,同时存在合并的上午、下午、午休。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
public class createMoveExcel {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);HSSFSheet sheet = workbook.getSheet("课程表");/*** 首先我需要将课程表格第一行空出来,所以要对下面的* 行进行下移操作。*/sheet.shiftRows(0,sheet.getLastRowNum(),1);/*** 插入午休 行,这里面为什么用6而不是5* 我们知道上午一般是4节课,加上星期行,* 按理应该从第五行下移一行,不要忘了前面* 我们下移了一行,所以应该从第6行执行,对Excel操作如果* 前面存在操作,我们应该考虑进来。*/ sheet.shiftRows(6,sheet.getLastRowNum(),1);/*** 开始我认为移动会自己创建行和列,因此我直接* 用方法想获取row以及cell,这时候报空指针,查API了解* shiftRows可以把某区域的行移动,但是移动后剩下的区域却为空* 因此我们需要创建*//*HSSFRow row=sheet.getRow(0);HSSFCell cell=row.getCell(0);cell.setCellValue("课程表");*/HSSFRow row=sheet.createRow(0);HSSFCell cell=row.createCell(0);cell.setCellValue("课程表");HSSFRow srow=sheet.createRow(6);HSSFCell scell=srow.createCell(0);scell.setCellValue("午休");/*** 合并单元格功能,对新增的第一行进行合并*/CellRangeAddress address=new CellRangeAddress(0,0,0,4);sheet.addMergedRegion(address);/*** 对新增的第六行进行合并*/CellRangeAddress secondaddress=new CellRangeAddress(6,6,0,4);sheet.addMergedRegion(secondaddress);/*** 对表格的修改以及其他操作需要在workbook.write之后才生效的*/	FileOutputStream os = new FileOutputStream("D:/课程表.xls");  workbook.write(os);  is.close(); os.close();} catch (Exception e) {e.printStackTrace();}}
}

上面代码思路是先将所有列运用HSSFSheet.shiftRows下移一行,

HSSFSheet.shiftRows(startRow, endRow, n)参数说明

startRow:需要移动的起始行;

endRow:需要移动的结束行;

n:移动的位置,正数表示向下移动,负数表示向上移动;

然后需要我们自己创建行和列,shiftRows可以把某区域的行移动,但是移动后剩下的区域却为空

 

创建新的行和列并且设置单元格以后,我们开始进行合并单元格。

CellRangeAddress address=new CellRangeAddress(0,0,0,5);

sheet.addMergedRegion(address);

CellRangeAddress对象其实就是表示一个区域,其构造方法如下:CellRangeAddress(firstRow, lastRow, firstCol, lastCol),参数的说明:

firstRow 区域中第一个单元格的行号

lastRow 区域中最后一个单元格的行号

firstCol 区域中第一个单元格的列号

lastCol 区域中最后一个单元格的列号

最后,我们要调用

 

FileOutputStream os = new FileOutputStream("D:/课程表.xls");   workbook.write(os);  

任何对表的修改或者其他操作,都在 workbook.write(os);  后生效的。

如图

wKiom1etGefhIXPfAAAgTYUvEes810.png

实例四 合并单元格

实例三我没有按照开始的想法插入合并的上午和下午单元格,因为HSSF没有提供移动列的方法,所以我们需要在实例二中开始生成课程表的时候就考虑加进去,现在我们对实例二进行修改,同时将实例三的代码加入实例二中。

import java.io.FileOutputStream;
import java.util.Random;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
public class createSimpleExcel {public static void main(String[] args) {try {HSSFWorkbook workbook=new HSSFWorkbook();/*** createSheet存在有参和无参两种形式,主要设置sheet名字*/HSSFSheet sheet=workbook.createSheet("课程表");HSSFRow firstrow=sheet.createRow(0);//创建第一行HSSFCell cell=firstrow.createCell(0);cell.setCellValue("课程表");CellRangeAddress address=new CellRangeAddress(0,0,0,5);sheet.addMergedRegion(address);/*** 我们知道课程表第一行是代表周一到周五,下面我们用两种方式创建Cell,* 一种用变量,另一种未用变量,用变量的好处后面可以体会到。*/HSSFRow sencodrow=sheet.createRow(1);//创建第二行//这里面我们第一列不用是因为第三行存在合并的上午单元格,自己体会下sencodrow.createCell(1).setCellValue("星期一");sencodrow.createCell(2).setCellValue("星期二");sencodrow.createCell(3).setCellValue("星期三");sencodrow.createCell(4).setCellValue("星期四");sencodrow.createCell(5).setCellValue("星期五");/*** 上面我们只是设置了首行,后面课程我们用同样的方法设置,* 这里面我们用循环方法设置课程*/Random random=new Random();String[] course={"语文","数学","英语","物理","化学","政治","历史","音乐","美术","体育"};//循环产生7行rowfor(int j=2;j<=9;j++){//每个row的1-5个cell设置值,我用随机取数组来写值。HSSFRow row_j=sheet.createRow(j);//第六行是午休if(j==6){row_j.createCell(0).setCellValue("午休");CellRangeAddress secondaddress=new CellRangeAddress(6,6,0,5);sheet.addMergedRegion(secondaddress);continue;}//每行开始都要空出一列来让我们能增加上午下午单元格for(int k=1;k<=5;k++){int i=random.nextInt(10);row_j.createCell(k).setCellValue(course[i]);}}sheet.getRow(2).createCell(0).setCellValue("上午");sheet.getRow(7).createCell(0).setCellValue("下午");CellRangeAddress thridaddress=new CellRangeAddress(2,5,0,0);sheet.addMergedRegion(thridaddress);CellRangeAddress fourthaddress=new CellRangeAddress(7,9,0,0);sheet.addMergedRegion(fourthaddress);FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();} catch (Exception e) {e.printStackTrace();}}
}

如图,已经初步可以看出来效果了。

wKioL1etHezz4NTgAAAlCRCkfYw267.png

实例五 单元格对齐

我们对字进行居中处理,HSSFCellStyle专门是创建修饰单元格的对象

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createStyleExcel {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);HSSFSheet sheet=workbook.getSheet("课程表");HSSFRow firstrow=sheet.getRow(0); //获取课程表行HSSFRow sencodrow=sheet.getRow(2);//获取上午行HSSFRow sixthrow=sheet.getRow(6);//获取午休行HSSFRow ninthrow=sheet.getRow(7);//获取下午行HSSFCellStyle style=workbook.createCellStyle();style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中firstrow.getCell(0).setCellStyle(style);sencodrow.getCell(0).setCellStyle(style);sixthrow.getCell(0).setCellStyle(style);ninthrow.getCell(0).setCellStyle(style);FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();is.close();} catch (Exception e) {e.printStackTrace();}	}
}

如图

wKiom1etI7miSckpAAAj7mq_zMQ287.png

上面代码我们用到了HSSFCellStyle的常量,以下是水平居中和垂直居中常量

  水平对齐相关参数

如果是左侧对齐就是 HSSFCellStyle.ALIGN_FILL;

如果是居中对齐就是 HSSFCellStyle.ALIGN_CENTER;

如果是右侧对齐就是 HSSFCellStyle.ALIGN_RIGHT;

如果是跨列举中就是 HSSFCellStyle.ALIGN_CENTER_SELECTION;

如果是两端对齐就是 HSSFCellStyle.ALIGN_JUSTIFY;

如果是填充就是 HSSFCellStyle.ALIGN_FILL;

     垂直对齐相关参数

如果是靠上就是 HSSFCellStyle.VERTICAL_TOP;

如果是居中就是 HSSFCellStyle.VERTICAL_CENTER;

如果是靠下就是 HSSFCellStyle.VERTICAL_BOTTOM;

如果是两端对齐就是 HSSFCellStyle.VERTICAL_JUSTIFY;

调整单元文字位置的方法还有以下几个:

setWrapText:自动换行,参数为boolean

setIndention;缩进

setRotation;文本旋转,这里的取值是从-90到90

实例六 使用边框

上面的课程表很明显的缺少边框,我们现在来给他加上。注意设置边框以及边框颜色都是针对单元格的,我们可以对row设置边框,但会将那一行全都被设置,因此我们需要再更细的单元格上操作。

边框和其他单元格设置一样也是调用CellStyle接口,CellStyle有2种和边框相关的属性,分别是:

 

边框相关属性说明范例
Border+ 方向边框类型BorderLeft, BorderRight 等
方向 +BorderColor边框颜色TopBorderColor,BottomBorderColor 等
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
public class createBoderExcel {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);HSSFSheet sheet=workbook.getSheet("课程表");HSSFCellStyle firststyle=workbook.createCellStyle();//第一种样式针对第一个单元格的,不存在右边线firststyle.setBorderTop(HSSFCellStyle.BORDER_THICK);firststyle.setBorderLeft(HSSFCellStyle.BORDER_THICK);firststyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);firststyle.setTopBorderColor(HSSFColor.PINK.index);firststyle.setLeftBorderColor(HSSFColor.PINK.index);firststyle.setBottomBorderColor(HSSFColor.BLUE.index);HSSFCellStyle secondstyle=workbook.createCellStyle();//第二种样式针对中间单元格的,不存在左右边线secondstyle.setBorderTop(HSSFCellStyle.BORDER_THICK);secondstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);		secondstyle.setTopBorderColor(HSSFColor.PINK.index);secondstyle.setBottomBorderColor(HSSFColor.BLUE.index);HSSFCellStyle thirdstyle=workbook.createCellStyle();//第三种样式针对最后单元格的,不存在左边线thirdstyle.setBorderTop(HSSFCellStyle.BORDER_THICK);thirdstyle.setBorderRight(HSSFCellStyle.BORDER_THICK);thirdstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);thirdstyle.setTopBorderColor(HSSFColor.PINK.index);thirdstyle.setRightBorderColor(HSSFColor.PINK.index);thirdstyle.setBottomBorderColor(HSSFColor.BLUE.index);HSSFRow firstrow=sheet.getRow(0);for(int i=0;i<firstrow.getLastCellNum();i++){if(i==0){firststyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);firstrow.getCell(i).setCellStyle(firststyle);}else if(i==firstrow.getLastCellNum()-1){firstrow.createCell(i);//注意前面实例针对第一行只创建了第一列,因此在这里我们需要创建列,不然不会设置边框firstrow.getCell(i).setCellStyle(thirdstyle);}else{firstrow.createCell(i);firstrow.getCell(i).setCellStyle(secondstyle);}}//发现对合并的单元格设置边框,居中效果居然没了,因此我们在这里补充FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();is.close();	}catch(Exception e){e.printStackTrace();}}
}

如图

wKiom1etQyfBD7oIAAAjjNxyQIo691.png

关于常量代表的边框对应如下:

wKiom1etQ1aSQ1ZEAABlf2IQzQE986.png

实例七 设置字体

注意因为对于单元格设置style,只要调用setCellStyle,其他代码设置的样式都会被清除,只会存在本次设置样式中保存的样式!

import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.record.cf.FontFormatting;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
public class createFontStyle {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);HSSFSheet sheet=workbook.getSheet("课程表");HSSFCellStyle style=workbook.createCellStyle();HSSFFont font = workbook.createFont();font.setFontName("微软雅黑");//设置字体名称font.setFontHeightInPoints((short) 10);//设置字号font.setColor(HSSFColor.RED.index);//设置字体颜色font.setUnderline(FontFormatting.U_SINGLE);//设置下划线font.setTypeOffset(FontFormatting.SS_SUPER);//设置上标下标font.setStrikeout(true);//设置删除线style.setFont(font);sheet.getRow(0).getCell(0).setCellStyle(style);FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();is.close();	}catch(Exception e){e.printStackTrace();}}
}

如图:

wKiom1etRGqDkLlbAAAismZbewE378.png

实例八 设置背景和纹理

import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
public class createBackGroundExcel {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);HSSFSheet sheet=workbook.getSheet("课程表");HSSFCellStyle style=workbook.createCellStyle();style.setFillForegroundColor(HSSFColor.GREEN.index);//设置图案颜色style.setFillBackgroundColor(HSSFColor.RED.index);//设置图案背景色style.setFillPattern(HSSFCellStyle. THICK_VERT_BANDS);//设置图案样式style.setAlignment(HSSFCellStyle.ALIGN_CENTER);style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);sheet.getRow(2).getCell(0).setCellStyle(style);FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();is.close();	}catch(Exception e){e.printStackTrace();}}
}

图片样式与对象常量对应:

wKiom1etRUfAyjrtAABd8oUxyTM688.png

如图:

wKioL1etRSeCDRq2AAAiS3boV-k330.png

实例九 设置宽度和长度

import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createWidthAndHeight {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);HSSFSheet sheet=workbook.getSheet("课程表");sheet.setColumnWidth(1, 20*256);sheet.getRow(0).setHeightInPoints(50);FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();is.close();	}catch(Exception e){e.printStackTrace();}}
}

如图:

wKioL1etRcXT3cxgAAAim1RUxx8188.png

      setColumnWidth的第二个参数要乘以256,这是怎么回事呢?其实,这个参数的单位是1/256个字符宽度,也就是说,这里是把B列的宽度设置为了31个字符。

     设置行高使用HSSFRow对象的setHeight和setHeightInPoints方法,这两个方法的区别在于setHeightInPoints的单位是点,而setHeight的单位是1/20个点,所以setHeight的值永远是setHeightInPoints的20倍。

       你也可以使用HSSFSheet.setDefaultColumnWidth、HSSFSheet.setDefaultRowHeight和HSSFSheet.setDefaultRowHeightInPoints方法设置默认的列宽或行高。

 

以上的是对HSSF基本用法的示范,下面我们来进行更进一步的补充说明:

实例十 创建文档摘要信息

import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createSummaryInformation {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);workbook.createInformationProperties();//创建文档信息DocumentSummaryInformation dsi= workbook.getDocumentSummaryInformation();//摘要信息dsi.setCategory("类别:Excel文件");//类别dsi.setManager("管理者:Liki");//管理者dsi.setCompany("公司:无");//公司SummaryInformation si = workbook.getSummaryInformation();//摘要信息si.setSubject("主题:课程表");//主题si.setTitle("标题:初中课程表");//标题si.setAuthor("作者:zyn");//作者si.setComments("备注:课程表展示");//备注FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();is.close();}catch(Exception e){e.printStackTrace();}}
}

如图:

wKioL1etZMjTblp0AAAsP0bLzPA644.png

实例十一 设置批注

import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFComment;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createPatriarch {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);HSSFSheet sheet=workbook.getSheet("课程表");HSSFPatriarch patr = sheet.createDrawingPatriarch();HSSFClientAnchor anchor = patr.createAnchor(0,0,0,0, 9,0, 11,6);//创建批注位置HSSFComment comment = patr.createCellComment(anchor);//创建批注comment.setString(new HSSFRichTextString("这是一个批注段落!"));//设置批注内容comment.setAuthor("ZYN");//设置批注作者comment.setVisible(true);//设置批注默认显示HSSFCell cell = sheet.getRow(0).getCell(0);cell.setCellComment(comment);FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();is.close();}catch(Exception e){e.printStackTrace();}}
}

如图:

wKioL1etajeCIF8dAAAwuvs06f0554.png

HSSFPatriarch.createAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2)方法参数说明:

 

  • dx1 - the x coordinate in EMU within the first cell.

  • dy1 - the y coordinate in EMU within the first cell.

  • dx2 - the x coordinate in EMU within the second cell.

  • dy2 - the y coordinate in EMU within the second cell.

  • col1 - the column (0 based) of the first cell.

  • row1 - the row (0 based) of the first cell.

  • col2 - the column (0 based) of the second cell.

  • row2 - the row (0 based) of the second cell.

     

实例十二 设置页眉和页脚

import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFFooter;
import org.apache.poi.hssf.usermodel.HSSFHeader;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createHeadAndFooter {public static void main(String[] args) {try{FileInputStream is = new FileInputStream("D:/课程表.xls");HSSFWorkbook workbook = new HSSFWorkbook(is);HSSFSheet sheet=workbook.getSheet("课程表");HSSFHeader header =sheet.getHeader();//得到页眉header.setLeft("页眉左边");header.setRight("页眉右边");header.setCenter("页眉中间");HSSFFooter footer =sheet.getFooter();//得到页脚footer.setLeft("页脚左边");footer.setRight("页脚右边");footer.setCenter("页脚中间");FileOutputStream out=new FileOutputStream("D:/课程表.xls");workbook.write(out);out.close();is.close();}catch(Exception e){e.printStackTrace();}}
}

也可以使用Office自带的标签定义,你可以通过HSSFHeader或HSSFFooter访问到它们,都是静态属性,列表如下:

HSSFHeader.tab &A 表名

HSSFHeader.file &F 文件名

HSSFHeader.startBold &B 粗体开始

HSSFHeader.endBold &B 粗体结束

HSSFHeader.startUnderline &U 下划线开始

HSSFHeader.endUnderline &U 下划线结束

HSSFHeader.startDoubleUnderline &E 双下划线开始

HSSFHeader.endDoubleUnderline &E 双下划线结束

HSSFHeader.time &T 时间

HSSFHeader.date &D 日期

HSSFHeader.numPages &N 总页面数

HSSFHeader.page &P 当前页号

实例十三 单元格格式操作

我们经常需要将单元格的数据进行格式化,比如时间、货币,HSSF提供格式化这些数据有两种实现方式,一种是内嵌格式,另一种是自定义格式。

import java.io.FileOutputStream;
import java.util.Date;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;public class createDataFormat {public static void main(String[] args) {try{HSSFWorkbook workbook = new HSSFWorkbook();HSSFSheet sheet=workbook.createSheet("格式转换");HSSFRow row0=sheet.createRow(0);/*** 时间格式转换* 我们用第一排第一个、第二个、第三个单元格都设置当前时间* 然后第一个单元格不进行任何操作,第二个单元格用内嵌格式,第三个单元格用自定义*/Date date=new Date();HSSFCell row1_cell1=row0.createCell(0);HSSFCell row1_cell2=row0.createCell(1);HSSFCell row1_cell3=row0.createCell(2);row1_cell1.setCellValue(date);row1_cell2.setCellValue(date);row1_cell3.setCellValue(date);HSSFCellStyle style1=workbook.createCellStyle();style1.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));HSSFCellStyle style2=workbook.createCellStyle();style2.setDataFormat(workbook.createDataFormat().getFormat("yyyy-mm-dd hh:m:ss"));row1_cell2.setCellStyle(style1);row1_cell3.setCellStyle(style2);/*** 第二排我们进行小数处理* 第一个不进行任何处理,第二个我们用内嵌格式保留两位,第三个我们用自定义*/HSSFRow row1=sheet.createRow(1);double db=3.1415926;HSSFCell row2_cell1=row1.createCell(0);HSSFCell row2_cell2=row1.createCell(1);HSSFCell row2_cell3=row1.createCell(2);row2_cell1.setCellValue(db);row2_cell2.setCellValue(db);row2_cell3.setCellValue(db);HSSFCellStyle style3=workbook.createCellStyle();style3.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00"));HSSFCellStyle style4=workbook.createCellStyle();style4.setDataFormat(workbook.createDataFormat().getFormat("0.00"));row2_cell2.setCellStyle(style3);row2_cell3.setCellStyle(style4);/*** 下面是进行货币的三种形式*/HSSFRow row2=sheet.createRow(2);double money=12345.6789;HSSFCell row3_cell1=row2.createCell(0);HSSFCell row3_cell2=row2.createCell(1);HSSFCell row3_cell3=row2.createCell(2);row3_cell1.setCellValue(money);row3_cell2.setCellValue(money);row3_cell3.setCellValue(money);HSSFCellStyle style5=workbook.createCellStyle();style5.setDataFormat(HSSFDataFormat.getBuiltinFormat("¥#,##0.00"));HSSFCellStyle style6=workbook.createCellStyle();style6.setDataFormat(workbook.createDataFormat().getFormat("¥#,##0.00"));row3_cell2.setCellStyle(style3);row3_cell3.setCellStyle(style4);FileOutputStream out=new FileOutputStream("D:/格式转换.xls");workbook.write(out);out.close();}catch(Exception e){e.printStackTrace();}}
}

如图:

 

 HSSFDataFormat.getFormat和HSSFDataFormat.getBuiltinFormat的区别: 当使用Excel内嵌的(或者说预定义)的格式时,直接用HSSFDataFormat.getBuiltinFormat静态方法即可。当使用自己定义的格式时,必须先调用HSSFWorkbook.createDataFormat(),因为这时在底层会先找有没有匹配的内嵌FormatRecord,如果没有就会新建一个FormatRecord,所以必须先调用这个方法,然后你就可以用获得的HSSFDataFormat实例的getFormat方法了,当然相对而言这种方式比较麻烦,所以内嵌格式还是用HSSFDataFormat.getBuiltinFormat静态方法更加直接一些。

拓展:

 判断单元格是否为日期类型,使用DateUtil.isCellDateFormatted(cell)方法。

实例十四 公式计算

很多人做过统计报表,都知道有时候我们需要用一列去统计其它列的数据,这时候我们经常会在这一列设置一个函数,下面我们用代码来实现这个功能,因为函数比较多,所以我会用较多的小例子分开说明以免代码过多混淆。

⑴基本计算

import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createFormula {public static void main(String[] args) {try{HSSFWorkbook workbook = new HSSFWorkbook();HSSFSheet sheet=workbook.createSheet("基本计算");HSSFRow row=sheet.createRow(0);HSSFCell cell0=row.createCell(0);cell0.setCellFormula("5*5+2");//可直接赋予一个简单的计算公式cell0=row.createCell(1);cell0.setCellValue(20);cell0=row.createCell(2);cell0.setCellFormula("A1+B1");cell0=row.createCell(3);cell0.setCellFormula("A1-B1");cell0=row.createCell(4);cell0.setCellFormula("A1*B1");cell0=row.createCell(5);cell0.setCellFormula("A1/B1");FileOutputStream out=new FileOutputStream("D:/基本计算.xls");workbook.write(out);out.close();}catch(Exception e){e.printStackTrace();}}
}

结果:

⑵SUM函数

import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class createFormula {public static void main(String[] args) {try{HSSFWorkbook workbook = new HSSFWorkbook();HSSFSheet sheet=workbook.createSheet("基本计算");HSSFRow row=sheet.createRow(0);row.createCell(0).setCellValue(1);row.createCell(1).setCellValue(2);row.createCell(2).setCellValue(3);row.createCell(3).setCellValue(4);row.createCell(4).setCellValue(5);row.createCell(5).setCellValue(6);row.createCell(6).setCellValue(7);//第七/八列进行计算,两种都等价A1+B1+C1+D1+E1+F1+G1row.createCell(7).setCellFormula("sum(A1,B1,C1,D1,E1,F1,G1)");row.createCell(8).setCellFormula("sum(A1:G1)");		FileOutputStream out=new FileOutputStream("D:/基本计算.xls");workbook.write(out);out.close();}catch(Exception e){e.printStackTrace();}}
}

结果:

wKioL1ete-qAeHpLAAAJof3pn_A701.png

⑶ABS绝对值、INT取整函数、ROUND四舍五入

import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;public class createABSDemo {public static void main(String[] args) {try{HSSFWorkbook workbook = new HSSFWorkbook();HSSFSheet sheet=workbook.createSheet("基本计算");HSSFRow row0=sheet.createRow(0);row0.createCell(0).setCellValue(-1234);row0.createCell(1).setCellValue(5678);HSSFRow row1=sheet.createRow(1);row1.createCell(0).setCellValue(23.456);row1.createCell(1).setCellValue(-54.562);HSSFRow row2=sheet.createRow(2);row2.createCell(0).setCellValue(8.49314);row2.createCell(1).setCellValue(12.927);/*** 取绝对值*/row0.createCell(2).setCellFormula("ABS(A1)");row0.createCell(3).setCellFormula("ABS(B1)");/*** 取整*/row1.createCell(2).setCellFormula("INT(A2)");row1.createCell(3).setCellFormula("INT(B2)");/*** 四舍五入*/row2.createCell(2).setCellFormula("ROUND(A3,1)");row2.createCell(3).setCellFormula("ROUND(B3,1)");FileOutputStream out=new FileOutputStream("D:/基本计算.xls");workbook.write(out);out.close();}catch(Exception e){e.printStackTrace();}}
}

对于公式我们这里就不一一列举了,Excel所有公式函数都可以通过设置cellFormula来设置。

HSSF针对xls文件操作还有很多其他方面的,但是从开发方面来说,上面已经满足我们日常导入导出报表开发功能,后面我会详细讲解web关于HSSF读取以及解析xls报表功能。

这篇关于Java POI(第一讲):POI中HSSF用法大全的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/521115

相关文章

springboot健康检查监控全过程

《springboot健康检查监控全过程》文章介绍了SpringBoot如何使用Actuator和Micrometer进行健康检查和监控,通过配置和自定义健康指示器,开发者可以实时监控应用组件的状态,... 目录1. 引言重要性2. 配置Spring Boot ActuatorSpring Boot Act

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

java如何分布式锁实现和选型

《java如何分布式锁实现和选型》文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zo... 目录引言:分布式锁的重要性与分布式系统中的常见问题和需求分布式锁的重要性分布式系统中常见的问题和需求

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

SpringCloud集成AlloyDB的示例代码

《SpringCloud集成AlloyDB的示例代码》AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能... 目录1.AlloyDBjavascript是什么?AlloyDB 的工作原理2.搭建测试环境3.代码工程1.

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python