我有一些包含表单控件的xlsm文件。我想以编程方式将每个工作表上的特定按钮向下移动几行。我的第一个希望是做这样的事情:
FileInputStream inputStream = new FileInputStream(new File("t.xlsm"));
XSSFWorkbook wb = new XSSFWorkbook(inputStream);
XSSFSheet xs = (XSSFSheet)wb.getSheetAt(1);
RelationPart rp = xs.getRelationParts().get(0);
XSSFDrawing drawing = (XSSFDrawing)rp.getDocumentPart();
for(XSSFShape sh : drawing.getShapes()){
XSSFClientAnchor a = (XSSFClientAnchor)sh.getAnchor();
if (sh.getShapeName().equals("Button 2")) {
a.setRow1(a.getRow1()+10);
a.setRow2(a.getRow2()+10);
}
}
但是,XSSFDrawing.getShapes()
给出的形状对象是副本,对它们的任何更改都不会在wb.write()
之后反映在文档中。
我尝试了其他一些方法,例如获取CTShape
并解析XML,但事情很快变得毛茸茸。
是否建议通过POI管理此类表单控件?
答案 0 :(得分:0)
我最终直接摆弄了XML:
wb = new XSSFWorkbook(new File(xlsmFile));
XSSFSheet s = wb.getSheet("TWO");
XmlObject[] subobj = s.getCTWorksheet().selectPath(declares+
" .//mc:AlternateContent/mc:Choice/main:controls/mc:AlternateContent/mc:Choice/main:control");
String targetButton = "Button 2";
int rowsDown = 10;
for (XmlObject obj : subobj) {
XmlCursor cursor = obj.newCursor();
cursor.push();
String attrName = cursor.getAttributeText(new QName("name"));
if (attrName.equals(targetButton)) {
cursor.selectPath(declares+" .//main:from/xdr:row");
if (!cursor.toNextSelection()) {
throw new Exception();
}
int newRow = Integer.parseInt(cursor.getTextValue()) + rowsDown;
cursor.setTextValue(Integer.toString(newRow));
cursor.pop();
cursor.selectPath(declares+" .//main:to/xdr:row");
if (!cursor.toNextSelection()) {
throw new Exception();
}
newRow = Integer.parseInt(cursor.getTextValue()) + rowsDown;
cursor.setTextValue(Integer.toString(newRow));
}
cursor.dispose();
}
这会将命名按钮向下移动10行。我不得不发现按钮名称(通过Excel可能不容易,我直接检查了文件)。我猜这对使用中的Excel版本非常敏感。