java excel checkbox,使用Apache POI(Java)在XLSX中创建复选框

这篇博客介绍了如何在使用Apache POI 4.0.1版本的Java程序中创建Excel工作表上的复选框。尽管库本身没有直接提供此功能,但通过操作VML绘图可以实现。作者详细展示了如何创建两种类型的复选框:遗产复选框和ActiveX复选框,重点讲解了遗产复选框的创建过程,包括获取或创建VML绘图,添加复选框形状类型以及添加具体复选框的方法。
摘要由CSDN通过智能技术生成

I need to create an Excel checkbox in an XSSFSheet, but I have found no obvious classes/methods for doing so in the Java Apache POI library (4.0.1), nor any examples. Any suggestions?

解决方案

There are two types of controls possible in Microsoft Excel. There are the legacy form controls and ActiveX controls. Creating legacy form controls would be possible. ActiveX controls wold be much more complex.

The legacy form controls are stored in VML drawings per sheet. Apache poi has a XSSFVMLDrawing class already because cell comments also are partially stored in VML drawings. But as often in apache poi the class is not complete and the accessibility of it's methods is set so that the class cannot easy extended. Seems as if apache poi developers often explicitly wants to prevent extension of their classes.

For legacy Checkbox controls we need a checkbox shape type and then checkbox shapes in this VML drawing.

Following code creates two legacy checkboxes.

The method XSSFVMLDrawing getVMLDrawing(XSSFSheet sheet) gets the VML drawing from the sheet or creates a new one if not already present.

The method void addCheckboxShapetype(XSSFVMLDrawing drawing) adds a new checkbox shape type to the drawing.

The method void addCheckbox(XSSFVMLDrawing drawing, int col1, int dx1, int row1, int dy1, int col2, int dx2, int row2, int dy2, String label, boolean checked) adds a new checkbox shape to the drawing having the given position and label and has a Checked element which contains either 1 when checked or 0 when not checked.

Complete example:

import java.io.*;

import org.apache.poi.openxml4j.opc.*;

import org.apache.poi.ooxml.POIXMLDocumentPart;

import org.apache.xmlbeans.*;

import org.apache.poi.xssf.usermodel.*;

import com.microsoft.schemas.vml.*;

import com.microsoft.schemas.office.excel.CTClientData;

import java.lang.reflect.Field;

import javax.xml.namespace.QName;

import java.util.List;

class CreateExcelLegacyDrawingControls {

private static XSSFVMLDrawing getVMLDrawing(XSSFSheet sheet) throws Exception {

XSSFVMLDrawing drawing = null;

if (sheet.getCTWorksheet().getLegacyDrawing() != null) {

String legacyDrawingId = sheet.getCTWorksheet().getLegacyDrawing().getId();

drawing = (XSSFVMLDrawing)sheet.getRelationById(legacyDrawingId);

} else {

int drawingNumber = sheet.getPackagePart().getPackage()

.getPartsByContentType(XSSFRelation.VML_DRAWINGS.getContentType()).size() + 1;

POIXMLDocumentPart.RelationPart rp =

sheet.createRelationship(XSSFRelation.VML_DRAWINGS, XSSFFactory.getInstance(), drawingNumber, false);

drawing = rp.getDocumentPart();

String rId = rp.getRelationship().getId();

sheet.getCTWorksheet().addNewLegacyDrawing().setId(rId);

}

return drawing;

}

private static void addCheckboxShapetype(XSSFVMLDrawing drawing) throws Exception {

String shapeTypeId = "_x0000_t201";

CTShapetype shapetype = CTShapetype.Factory.newInstance();

shapetype.setId(shapeTypeId);

shapetype.setCoordsize("21600,21600");

shapetype.setSpt(201);

shapetype.setPath2("m,l,21600r21600,l21600,xe");

Field _items = XSSFVMLDrawing.class.getDeclaredField("_items");

_items.setAccessible(true);

@SuppressWarnings("unchecked") //we know the problem and expect runtime error if it possibly occurs

List items = (List)_items.get(drawing);

Field _qnames = XSSFVMLDrawing.class.getDeclaredField("_qnames");

_qnames.setAccessible(true);

@SuppressWarnings("unchecked") //we know the problem and expect runtime error if it possibly occurs

List qnames = (List)_qnames.get(drawing);

items.add(shapetype);

qnames.add(new QName("urn:schemas-microsoft-com:vml", "shapetype"));

}

private static void addCheckbox(XSSFVMLDrawing drawing,

int col1, int dx1, int row1, int dy1, int col2, int dx2, int row2, int dy2,

String label, boolean checked) throws Exception {

String shapeTypeId = "_x0000_t201";

Field _shapeId = XSSFVMLDrawing.class.getDeclaredField("_shapeId");

_shapeId.setAccessible(true);

int shapeId = (int)_shapeId.get(drawing);

_shapeId.set(drawing, shapeId + 1);

CTShape shape = CTShape.Factory.newInstance();

shape.setId("_x0000_s" + shapeId);

shape.setType("#" + shapeTypeId);

shape.setFilled(com.microsoft.schemas.vml.STTrueFalse.F);

shape.setStroked(com.microsoft.schemas.vml.STTrueFalse.F);

String textboxHTML =

"

"

+"" + label + ""

+"

";

CTTextbox[] textboxArray = new CTTextbox[1];

textboxArray[0] = CTTextbox.Factory.parse(textboxHTML);

textboxArray[0].setStyle("mso-direction-alt:auto");

textboxArray[0].setSingleclick(com.microsoft.schemas.office.office.STTrueFalse.F);

shape.setTextboxArray(textboxArray);

CTClientData cldata = shape.addNewClientData();

cldata.setObjectType(com.microsoft.schemas.office.excel.STObjectType.CHECKBOX);

cldata.addNewMoveWithCells();

cldata.addNewSizeWithCells();

cldata.addNewAnchor().setStringValue(

"" + col1 + ", " + dx1 + ", " + row1 + ", " +dy1 + ", " + col2 + ", " + dx2 + ", " + row2 + ", " + dy2

);

cldata.addAutoFill(com.microsoft.schemas.office.excel.STTrueFalseBlank.FALSE);

cldata.addAutoLine(com.microsoft.schemas.office.excel.STTrueFalseBlank.FALSE);

cldata.addTextVAlign("Center");

cldata.addNoThreeD(com.microsoft.schemas.office.excel.STTrueFalseBlank.TRUE);

cldata.addChecked((checked)?java.math.BigInteger.valueOf(1):java.math.BigInteger.valueOf(0));

Field _items = XSSFVMLDrawing.class.getDeclaredField("_items");

_items.setAccessible(true);

@SuppressWarnings("unchecked") //we know the problem and expect runtime error if it possibly occurs

List items = (List)_items.get(drawing);

Field _qnames = XSSFVMLDrawing.class.getDeclaredField("_qnames");

_qnames.setAccessible(true);

@SuppressWarnings("unchecked") //we know the problem and expect runtime error if it possibly occurs

List qnames = (List)_qnames.get(drawing);

items.add(shape);

qnames.add(new QName("urn:schemas-microsoft-com:vml", "shape"));

}

public static void main(String[] args) throws Exception {

XSSFWorkbook workbook = new XSSFWorkbook();

//following is necessary to be textboxHTML of the CTShape compatible with Excel 2007.

//

workbook.getCTWorkbook().addNewFileVersion().setAppName("xl");

workbook.getCTWorkbook().getFileVersion().setLastEdited("4");

workbook.getCTWorkbook().getFileVersion().setLowestEdited("0");

workbook.getCTWorkbook().getFileVersion().setRupBuild("4507");

XSSFSheet sheet = workbook.createSheet();

XSSFCell cell = sheet.createRow(5).createCell(5);

/*

XSSFDrawing drawing = sheet.createDrawingPatriarch();

XSSFClientAnchor anchor = workbook.getCreationHelper().createClientAnchor();

anchor.setCol1(cell.getColumnIndex());

anchor.setCol2(cell.getColumnIndex()+1);

anchor.setRow1(cell.getRow().getRowNum());

anchor.setRow2(cell.getRow().getRowNum()+3);

XSSFComment comment = drawing.createCellComment(anchor);

XSSFRichTextString str = workbook.getCreationHelper().createRichTextString("Hello, World!");

comment.setString(str);

comment.setAuthor("Apache POI");

cell.setCellComment(comment);

*/

XSSFVMLDrawing vmlDrawing = getVMLDrawing(sheet);

addCheckboxShapetype(vmlDrawing);

addCheckbox(vmlDrawing, 1, 0, 1, 0, 3, 0, 2, 0, "Checkbox 1", true);

addCheckbox(vmlDrawing, 1, 0, 2, 0, 3, 0, 3, 0, "Checkbox 2", false);

FileOutputStream out = new FileOutputStream("Excel.xlsx");

workbook.write(out);

out.close();

workbook.close();

}

}

Please note, for above solution the full jar of all of the schemas ooxml-schemas-1.4.jar (lower versions for older releases) is needed as mentioned in FAQ N10025.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Java POIExcel时,可以使用`XSSF`模块的`XSSFClientAnchor`和`XSSFDrawing`类来插入复选框并打勾。 以下是一个示例代码,可以在第一行添加一个带有复选框的单元格: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.*; public class ExcelWriter { public static void main(String[] args) throws Exception { // Create a workbook XSSFWorkbook workbook = new XSSFWorkbook(); // Create a sheet XSSFSheet sheet = workbook.createSheet("Sheet1"); // Create a row XSSFRow row = sheet.createRow(0); // Create a cell with checkbox XSSFCell cell = row.createCell(0); cell.setCellValue("Select"); // Create a drawing canvas XSSFDrawing drawing = sheet.createDrawingPatriarch(); // Create an anchor and attach the checkbox to it XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 2, 2); XSSFSimpleShape shape = drawing.createSimpleShape(anchor); shape.setShapeType(FormControlType.CHECK_BOX); shape.setFillColor(IndexedColors.WHITE.getIndex()); shape.setLineStyleColor(IndexedColors.BLACK.getIndex()); // Check the checkbox shape.getCTShape().getOleObject().getFormData().setCheckboxState(true); // Save the workbook workbook.write(new FileOutputStream("test.xlsx")); workbook.close(); } } ``` 在上面的代码,我们使用`XSSFClientAnchor`类创建了一个锚点,并使用`XSSFDrawing`类创建了一个绘图工具。接下来,我们使用`XSSFSimpleShape`类创建了一个简单形状,并将其附加到锚点上。我们设置了形状类型为`CHECK_BOX`,并设置了填充颜色和线条颜色。最后,我们使用`getCTShape()`方法获取形状的CTShape实例,并使用`getOleObject()`方法获取OLE对象,从而设置复选框的状态为“选”。 执行上面的代码,您将在Excel文档看到一个带有复选框的单元格,并且该单元格已经被选
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值