POI 支持调用MS-Office 绘图工具进行图形的绘制。一张sheet页上的图形是按照有层级的图形组和图形来安排的。最顶层的图形是patriarch,它在sheet页上是不可见的。在开始绘制图形之前,您需要在HSSFSheet 对象中调用createPatriarch方法。调用这个方法会清除在该sheet页中储存的所有的图形信息。默认情况下只要这个方法不被调用,POI不会将图形数据清除。
要创建一个图形,您需要做以下几步:
1. 创建一个patriarch 对象
2. 创建一个锚点以供图形在sheet页上定位
3. 调用patriarch对象创建一个图形
4. 设置图形类型(直线,椭圆,矩形等等)
5. 设置图形的其他样式细节(例如:线条粗细等等)
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 );
HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
文本框的创建方式如下:
HSSFTextbox textbox1 = patriarch.createTextbox(
new HSSFClientAnchor(0,0,0,0,(short)1,1,(short)2,2));
textbox1.setString(new HSSFRichTextString("This is a test") );
在同一文本框中设置不同的字体样式也是可以实现的
HSSFFont font = wb.createFont();
font.setItalic(true);
font.setUnderline(HSSFFont.U_DOUBLE);
HSSFRichTextString string = new HSSFRichTextString("Woo!!!");
string.applyFont(2,5,font);
textbox.setString(string );
Just as can be done manually using Excel, it is possible to group shapes together. This is done by calling createGroup() and then creating the shapes using those groups.
如同Excel中可以手动设置组一样,调用createGroup()方法,用新建的组创建图形也可以实现。组中也可以嵌套其他组。
注意
任何一个组中必须至少包含两个不同图形或是其他的子组。
创建图片组可以参考下面的例子:
// 创建一个图片组.
HSSFShapeGroup group = patriarch.createGroup(
new HSSFClientAnchor(0,0,900,200,(short)2,2,(short)2,2));
//在图片组中创建多条直线.
HSSFSimpleShape shape1 = group.createShape(new HSSFChildAnchor(3,3,500,500));
shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
( (HSSFChildAnchor) shape1.getAnchor() ).setAnchor((short)3,3,500,500);
HSSFSimpleShape shape2 = group.createShape(new HSSFChildAnchor((short)1,200,400,600));
shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
如果您足够细心,您将会发下,在图形组中添加的图形使用的是一个新类型的锚点对象HSSFChildAnchor。这是因为新创建的组会有自己的坐标空间。在POI中,这个 坐标空间默认为(0,0,1023,255),但是您也可以根据自己的意愿进行修改。
myGroup.setCoordinates(10,10,20,20); // top-left, bottom-right
如果您在一个图片组中加入了另外一个图片组,同样该子图片组也有自己的坐标空间。
默认的图片演示看起来有些平常。为图形设置不同的样式也可以通过POI来实现。不过现在仅能支持以下几种图形样式改变:
l 变换填充色
l 去除填充色
l 改变线条粗细
l 改变线条样式 比如:虚线,点线等等
l 改变线条颜色
以下是如何实现
HSSFSimpleShape s = patriarch.createSimpleShape(a);
s.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
s.setLineStyleColor(10,10,10);
s.setFillColor(90,10,200);
s.setLineWidth(HSSFShape.LINEWIDTH_ONE_PT * 3);
s.setLineStyle(HSSFShape.LINESTYLE_DOTSYS);
虽然推荐使用本地POI命名来创建图形,但有时我们也希望调用标准AIP获得和外部库的兼容性。处于这目的我们对Graphics 和Graphics2d 类进行了扩充。
注意:
在开始使用之前,您需要知道Graphics2d对MS-office 绘图命令的支持不是很好,虽然Graphics类比起来对MS-office绘图命令更加兼容,但仍然差强人意。
所有的绘图指令都封装在HSSFShapeGroup类中。以下是它们的用法:
a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 );
group = patriarch.createGroup( a );
group.setCoordinates( 0, 0, 80 * 4 , 12 * 23 );
float verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / (float)Math.abs(group.getY2() - group.getY1());
g = new EscherGraphics( group, wb, Color.black, verticalPointsPerPixel );
g2d = new EscherGraphics2d( g );
drawChemicalStructure( g2d );
首先我们做的是为我们将要进行的绘制创建一个组并设置它的坐标。接下来,我们计算出一个合理的 fontSizeMultipler 创建一个EscherGraphics对象。因为我们想得到的是Graphics2d对象,所以我们我们新建一个EscherGraphics2d对象并把它传入一个创建好的Graphics对象中。最后我们会通过一系列流程将它绘制成一个EscherGraphics2d对象。
在垂直方向上每个点的像素值还需要再深入说明一下。在将Graphics对象调用转化成Escher 对象调用中遇到的一个困难是,在Excel中没有明确的对绝对位置的像素定义。在Excel中,单元格的宽度是用“字符”宽度,高度是用“点”来度量的。不幸的是,在Excel中并没有明确的定义被用来度量的字符的类型。估计是由于Excel想在不同的平台上或是在同一平台上使用不同的字体造成的。
因为这些限制,我们必须要实现一个标准verticalPointsPerPixel 用来度量每个垂直方向点所占的像素。当您调用像是drawString()这样的方法时,所用到的字体的verticalPointsPerPixel度量值必须明确。
计算verticalPointsPerPixel值的公式如下:
multipler = groupHeightInPoints / heightOfGroup
图形组的高度可以通过简单的计算不同图形边界盒的Y轴坐标来得到。 获得图新组的高度也可以简单的调用以下这个方法:
HSSFClientAnchor.getAnchorHeightInPoints().
许多Graphic 类支持的方法还没有实现,现在已知实现的方法是:
- fillRect()
- fillOval()
- drawString()
- drawOval()
- drawLine()
- clearRect()
现在还不支持的方法会调用POI日志机制返回并记录日志信息(默认为disabled)
提纲
提纲对将不同部分的信息聚合在一起非常重要。它可以用POI提供的API简单的这样实现:
Workbook wb = new HSSFWorkbook();
Sheet sheet1 = wb.createSheet("new sheet");
sheet1.groupRow( 5, 14 );
sheet1.groupRow( 7, 14 );
sheet1.groupRow( 16, 19 );
sheet1.groupColumn( (short)4, (short)7 );
sheet1.groupColumn( (short)9, (short)12 );
sheet1.groupColumn( (short)10, (short)11 );
FileOutputStream fileOut = new FileOutputStream(filename);
wb.write(fileOut);
fileOut.close();
折叠(或展开)一个提纲,可以用以下的方法:
sheet1.setRowGroupCollapsed( 7, true );
sheet1.setColumnGroupCollapsed( (short)4, true );
被选中的行或列必须包含一个已经创建好的组,可以是组内的任意位置。
图像是绘图支持的一部分。提价一张图片可以用最高级别的Drawing对象调用createPicture()。现在支持的图片格式有:
应当值得注意的是任何已经存在的绘图可能会因为您添加一张图片到sheet页上而被清除
插入图片
//创建一个新的工作簿
Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
//为工作簿添加图片.
InputStream is = new FileInputStream("image1.jpeg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
is.close();
CreationHelper helper = wb.getCreationHelper();
//创建sheet页
Sheet sheet = wb.createSheet();
// 创建顶层的Drawing对象,它是所有图形和图像的载体
Drawing drawing = sheet.createDrawingPatriarch();
//添加一个图片图形
ClientAnchor anchor = helper.createClientAnchor();
//设置图形左上角的位置
//然后调用 Picture 的resize() 方法,自动关联到新坐标
anchor.setCol1(3);
anchor.setRow1(2);
Picture pict = drawing.createPicture(anchor, pictureIdx);
//自动关联到新坐标
pict.resize();
//保存到工作簿
String file = "picture.xls";
if(wb instanceof XSSFWorkbook) file += "x";
FileOutputStream fileOut = new FileOutputStream(file);
wb.write(fileOut);
fileOut.close();
注意
Picture.resize() 现仅支持JPEG和PNG格式的图片,其他格式暂不支持
从工作簿中读取图片
List lst = workbook.getAllPictures();
for (Iterator it = lst.iterator(); it.hasNext(); ) {
PictureData pict = (PictureData)it.next();
String ext = pict.suggestFileExtension();
byte[] data = pict.getData();
if (ext.equals("jpeg")){
FileOutputStream out = new FileOutputStream("pict.jpg");
out.write(data);
out.close();
}
}
关联范围是用一个名字代表一组单元格的方式。关联单元格是关联范围的下一级一组单元格中的一个。您可以用他们的关联范围创建或是得到对应的单元格。当要处理关联范围时可以用org.apache.poi.hssf.util.CellReference和org.apache.poi.hssf.util.AreaReference两个类(除了包名不一样外,在XSSF和HSSF中同样有这两个类)
创建管理范围/关联单元格
// 准备数据
String sname = "TestSheet", cname = "TestName", cvalue = "TestVal";
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet(sname);
sheet.createRow(0).createCell((short) 0).setCellValue(cvalue);
//1.用空间引用为一个单元格创建关联范围
Name namedCell = wb.createName();
namedCell.setNameName(cname);
String reference = sname+"!A1:A1"; // 空间引用
namedCell.setRefersToFormula(reference);
// 2.用单元格引用为一个单元格创建关联范围
Name namedCel2 = wb.createName();
namedCel2.setNameName(cname);
String reference = sname+"!A1"; //单元格引用
namedCel2.setRefersToFormula(reference);
// 3. 用空间引用为一组单元格创建关联范围
Name namedCel3 = wb.createName();
namedCel3.setNameName(cname);
String reference = sname+"!A1:C5"; // 空间引用
namedCel3.setRefersToFormula(reference);
// 4. 创建关联方程
Name namedCel4 = wb.createName();
namedCel4.setNameName("my_sum");
namedCel4.setRefersToFormula("SUM(sname+!$I$2:$I$6)");
从关联范围/关联单元格读取数据
// 准备数据
String cname = "TestName";
Workbook wb = getMyWorkbook(); // 获得工作簿
//获得关联范围
int namedCellIdx = wb.getNameIndex(cellName);
Name aNamedCell = wb.getNameAt(namedCellIdx);
//在关联范围中获得单元格并检测它的内容
AreaReference aref = new AreaReference(aNamedCell.getRefersToFormula());
CellReference[] crefs = aref.getAllReferencedCells();
for (int i=0; i<crefs.length; i++) {
Sheet s = wb.getSheet(crefs[i].getSheetName());
Row r = sheet.getRow(crefs[i].getRow());
Cell c = r.getCell(crefs[i].getCol());
//根据单元格数据格式取出单元格内容。。。。。。.
}
从不连续的关联范围中读取数据
// 准备数据
String cname = "TestName";
Workbook wb = getMyWorkbook(); // retrieve workbook
// 获得关联范围
// Will be something like "$C$10,$D$12:$D$14";
int namedCellIdx = wb.getNameIndex(cellName);
Name aNamedCell = wb.getNameAt(namedCellIdx);
//在关联范围中获得单元格并检测它的内容
//将会返回C10单元格和D12到D14单元格的空间引用
AreaReference[] arefs = AreaReference.generateContiguous(aNamedCell.getRefersToFormula());
for (int i=0; i<arefs.length; i++) {
// Only get the corners of the Area
// (use arefs[i].getAllReferencedCells() to get all cells)
CellReference[] crefs = arefs[i].getCells();
for (int j=0; j<crefs.length; j++) {
// Check it turns into real stuff
Sheet s = wb.getSheet(crefs[j].getSheetName());
Row r = s.getRow(crefs[j].getRow());
Cell c = r.getCell(crefs[j].getCol());
// 对此单元格进行相应的处理。。。。。。
}
}
注意:
当单元格被删除的时候,Excel并不会删除和它关联的关联范围。因此,在工作簿中会存在关联范围指向不存在的单元格的情况。在创建空间引用时应该先验证两者之间的关联引用是否正确。
if(name.isDeleted()){
//关联范围指向一个不存在的单元格
} else {
AreaReference ref = new AreaReference(name.getRefersToFormula());
}
注释是不同于单元格的内容是附属于或者从属与单元格的富文本。注释的内容是独立于单元格独自存储的,并且是在绘制对象中展示的(比如一个文本框),因此它既独立于单元格同时又与单元格紧密联系。
添加注释
Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
CreationHelper factory = wb.getCreationHelper();
Sheet sheet = wb.createSheet();
Cell cell = sheet.createRow(3).createCell(5);
cell.setCellValue("F4");
我的博客地址:www.aitawo.com
分享到:
相关推荐
### POI3.5 HSSF 和XSSF Excel操作快速入门手册 #### 一、简介 Apache POI 是一个用于读写Microsoft Office格式文件的Java API,包括但不限于Excel、Word等。其中,HSSF用于处理Excel 97-2003格式(.xls),而XSSF则...
### POI3.5 HSSF 和 XSSF Excel 操作快速入门手册 #### 一、POI简介与背景 Apache POI 是一个强大的 Java API,用于处理 Microsoft Office 格式的文件,包括 Excel 和 Word。其中,HSSF 和 XSSF 分别是 POI 提供的...
本手册是POI操作Excel文件的快速入门指南,旨在帮助开发者快速掌握使用HSSF和XSSF进行Excel文件操作的基本方法。通过阅读和实践本手册中的内容,用户可以学会如何添加POI支持、创建新工作簿、创建新的sheet页、操作...
在本文中,我们将重点关注如何使用POI 3.5版本中的HSSF和XSSF库来读写Excel文件。 HSSF(Horizontally Stored Sheet Format)是POI针对旧版BIFF格式(Excel 97-2007)的API,而XSSF(XML Spreadsheet Format)则是...
### POI3.5-HSSF和XSSF-Excel操作快速入门 #### 一、简介与背景 Apache POI是Java编程语言中一个强大的工具包,用于处理Microsoft Office格式的文件,包括Excel、Word和PowerPoint等。POI的HSSF组件主要用于处理...
Apache POI HSSF和XSSF读写EXCEL总结
。Apache 1.。POI HSSF和XSSF读写EXCEL总结.pdf
。Apache 1.。POI HSSF和XSSF读写EXCEL总结.docx
在本文中,我们将深入探讨如何使用POI库中的HSSF和XSSF组件来读取和写入Excel文件,这两种组件分别用于处理.xls(97-2003版Excel格式)和.xlsx(2007及更高版本的Office Open XML格式)。 首先,让我们了解HSSF...
在"poi-3.8-POI-HSSF和POI-XSSF和SXSSF.rar"这个压缩包中,主要涵盖了POI项目对Excel文件处理的三个关键组件:HSSF、XSSF和SXSSF。 1. HSSF (Horrible Spreadsheet Format):这是POI项目早期开发的一个API,用于...
它提供了两种主要的接口,HSSF(Horrible Spreadsheet Format)和XSSF(XML Spreadsheet Format),分别用于处理老版本的.BIFF8格式(Excel 97-2003)和较新的.XLSX XML格式(Excel 2007及以上版本)。 **HSSF** 是...
在POI 3.5中,主要关注的是HSSF(Horizontally SpreadSheet Format)和XSSF(XML SpreadSheet Format)两个组件,分别用于处理老版的.xls Excel文件和新版的.xlsx Excel文件。这两个组件提供了工作簿(Workbook)、...
### Apache POI HSSF and XSSF 快速指南帮助文档 API poi-3.15 #### 一、Apache POI 概述 Apache POI 是一个用于读取和写入 Microsoft Office 格式文件(如 Word 和 Excel)的开源 Java 库。它支持多种格式,包括...
Apache POI 是一个开源项目,专门用于处理微软的Office文档格式,如Excel(.xls 和 .xlsx)、Word(.doc 和 .docx)以及PowerPoint(.ppt 和 .pptx)。在Java环境中,Apache POI 提供了丰富的API,使得开发者能够...
- **HSSF和XSSF**: POI 3.5支持两种类型的Excel文件,即旧版的.HSSF(Horrible Spreadsheet Format)用于处理BIFF8格式的.xls文件,而.XSSF则用于处理OOXML格式的.xlsx文件。这两种API都提供了创建、读取和修改工作...
Apache POI提供了HSSF(Horrible Spreadsheet Format)和XSSF(XML Spreadsheet Format)两个主要组件,分别用于读写旧版的.BIFF8格式(Excel 97-2007)和OOXML(Office Open XML)格式的Excel文件。 在HSSF中,...
2. **XSSF(XML Spreadsheet Format)**: 针对Excel 2007及以上版本的.xlsx文件,POI提供了XSSF组件。它支持更多的功能和样式,因为.xlsx格式基于Office Open XML标准。与HSSF类似,XSSF也提供了一套API来创建、修改...
总的来说,Apache POI 3.5 jar包提供了全面的工具集,使得Java开发者能够方便地处理Microsoft Office文件,特别是在Excel的旧版和OOXML格式之间进行操作。通过这些库,开发者可以创建应用程序,读取、分析、编辑和...
POI提供API给Java程式对Microsoft Office格式档案读和写的功能。 结构: HSSF - 提供读写Microsoft Excel格式档案的功能。 XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。 HWPF - 提供读写...
POI_3.8_API.CHM; POI3.5_HSSF_和XSSF_Excel操作快速入门手册.pdf; poi-bin-3.9-20121203.zip; poi使用总结.txt; POI整理.doc;