В привязке индекс col1
всегда должен быть ниже, чем col2
, а индекс row1
должен быть ниже, чем row2
. Нарисованные линии в якорях всегда сверху вниз слева направо. При необходимости вы можете перевернуть их по вертикали.
Так, если, например, необходимо нарисовать линию от B14
до G4
, вы создаете якорь B4:G14
, рисуете линию и затем переворачиваете фигуру по вертикали. .
shape.getCTShape().getSpPr().getXfrm().setFlipV(true);
Полный пример:
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.ShapeTypes;
import org.apache.poi.util.Units;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import java.io.FileOutputStream;
class CreateExcelLineShapesArrows {
static XSSFSimpleShape drawLine(XSSFCell fromCell, XSSFCell toCell) {
XSSFWorkbook wb = fromCell.getSheet().getWorkbook();
XSSFCreationHelper helper = wb.getCreationHelper();
XSSFSheet sheet = fromCell.getSheet();
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = helper.createClientAnchor();
int fromCol = Math.min(fromCell.getColumnIndex(), toCell.getColumnIndex());
int toCol = Math.max(fromCell.getColumnIndex(), toCell.getColumnIndex());
int fromRow = Math.min(fromCell.getRow().getRowNum(), toCell.getRow().getRowNum());
int toRow = Math.max(fromCell.getRow().getRowNum(), toCell.getRow().getRowNum());
anchor.setCol1(fromCol);
anchor.setRow1(fromRow); // anchor starts top left of this cell
anchor.setDy1(Units.toEMU(sheet.getRow(fromRow).getHeightInPoints()/2)); //plus 1/2 row height
anchor.setCol2(toCol);
anchor.setRow2(toRow);// anchor ends top left of this cell
anchor.setDy2(Units.toEMU(sheet.getRow(toRow).getHeightInPoints()/2)); //plus 1/2 row height
XSSFSimpleShape shape = drawing.createSimpleShape(anchor);
shape.setShapeType(ShapeTypes.LINE);
shape.setLineWidth(1);
shape.setLineStyleColor(0, 0, 0);
if (fromCell.getRow().getRowNum() > toCell.getRow().getRowNum()) { // if fromCell's row is below toCells's row, then flip vertically
shape.getCTShape().getSpPr().getXfrm().setFlipV(true);
}
return shape;
}
static void setTailEndTriangle(XSSFSimpleShape shape) {
CTShapeProperties shapeProperties = shape.getCTShape().getSpPr();
CTLineProperties lineProperties = shapeProperties.getLn();
CTLineEndProperties lineEndProperties = CTLineEndProperties.Factory.newInstance();
lineEndProperties.setType(STLineEndType.TRIANGLE);
//lineEndProperties.setLen(STLineEndLength.LG);
//lineEndProperties.setW(STLineEndWidth.LG);
lineProperties.setTailEnd(lineEndProperties);
}
static void setHeadEndTriangle(XSSFSimpleShape shape) {
CTShapeProperties shapeProperties = shape.getCTShape().getSpPr();
CTLineProperties lineProperties = shapeProperties.getLn();
CTLineEndProperties lineEndProperties = CTLineEndProperties.Factory.newInstance();
lineEndProperties.setType(STLineEndType.TRIANGLE);
//lineEndProperties.setLen(STLineEndLength.LG);
//lineEndProperties.setW(STLineEndWidth.LG);
lineProperties.setHeadEnd(lineEndProperties);
}
public static void main(String[] args) throws Exception{
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet("Sheet1");
XSSFCell cellG4 = sheet.createRow(3).createCell(6); cellG4.setCellValue("Test A");
XSSFCell cellA14 = sheet.createRow(13).createCell(0); cellA14.setCellValue("Test");
XSSFCell cellB14 = sheet.getRow(13).createCell(1);
XSSFCell cellG23 = sheet.createRow(22).createCell(6); cellG23.setCellValue("Test B");
XSSFSimpleShape shape = drawLine(cellB14, cellG23);
setTailEndTriangle(shape);
shape = drawLine(cellB14, cellG4);
setTailEndTriangle(shape);
FileOutputStream out = new FileOutputStream("CreateExcelLineShapesArrows.xlsx");
wb.write(out);
out.close();
wb.close();
}
}
Результат: