Is it possible to draw a line in java poi at mid-angle within a cell?

Solution 1:

As commented already main suggestion to you is to use cell border lines instead of line shapes. Cell border lines are one of the main features of a spreadsheet. Shapes are not. That's why shapes are much more complicated to use than cell border lines.

But of course drawing line shapes is possible.

The position and size of the shapes is determined by the anchor. One can think about shapes floating in the drawing layer over the cells. The anchor anchors them on the cell edges. According to the positions of the cells they are anchored to, shapes also will stretched or compressed. So also the size is determined by the anchor.

A ClientAnchor has following properties:

Col1 = top left edge of the shape is ancored on left edge of that column

Row1 = top left edge of the shape is ancored on top edge of that row

Col2 = bottom right edge of the shape is ancored on left edge of that column

Row2 = bottom right edge of the shape is ancored on top edge of that row

Dx1 = delta x to shift top left edge of the shape away from the left edge of the Col1

Dy1 = delta y to shift top left edge of the shape away from the top edge of the Row1

Dx2 = delta x to shift bottom right edge of the shape away from the left edge of the Col2

Dy2 = delta y to shift bottom right edge of the shape away from the top edge of the Row2

Note, measurement unit for dx and dy is EMU (English Metric Unit). There is Units to handle those strange measurement units properly.

Complete example:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.util.Units;

import java.io.FileOutputStream;

class CreateExcelLineShapesParallel {
    
 static void drawLine(XSSFDrawing xssfdrawing, XSSFClientAnchor xssfanchor) {
  XSSFSimpleShape xssfshape = xssfdrawing.createSimpleShape(xssfanchor);
  xssfshape.setShapeType(ShapeTypes.LINE);
  xssfshape.setLineWidth(1);
  xssfshape.setLineStyle(0);
  xssfshape.setLineStyleColor(0, 0, 0);
 }
 
 static ClientAnchor getAnchorHorizontalFromCell(CreationHelper helper, Cell cell) {
  //anchor determines the size of the line shape to be from 
  //upper left edge of cell to upper left edge of next cell in row
  ClientAnchor anchor = helper.createClientAnchor();
  anchor.setCol1(cell.getColumnIndex());
  anchor.setRow1(cell.getRowIndex()); 
  anchor.setCol2(cell.getColumnIndex()+1);
  anchor.setRow2(cell.getRowIndex());
  //dx and dy in anchor to shift it away from the edges of the cell
  //all initialized to 0
  anchor.setDx1(0);
  anchor.setDx2(0);
  anchor.setDy1(0);
  anchor.setDy2(0);
  return anchor;
 }

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

  Workbook workbook = new XSSFWorkbook(); String filePath = "./CreateExcelLineShapesParallel.xlsx";
  
  CellStyle style = workbook.createCellStyle();
  style.setAlignment(HorizontalAlignment.CENTER);
  style.setVerticalAlignment(VerticalAlignment.CENTER);
    
  Sheet sheet = workbook.createSheet("Sheet1");
  
  int rowHeightInPt = 30;
  int lineMarginTopAndBottomInPt = 5;
  
  Row row = sheet.createRow(5);
  row.setHeightInPoints(rowHeightInPt);
  Cell cell = row.createCell(5);
  cell.setCellValue("Hello");
  cell.setCellStyle(style);

  CreationHelper helper = workbook.getCreationHelper();
  Drawing drawing = sheet.createDrawingPatriarch();

  ClientAnchor anchor = getAnchorHorizontalFromCell(helper, cell);
  //dx and dy in anchor to shift it away from the edges of the cell
  //measurement unit for dx and dy is EMU (English Metric Unit)
  anchor.setDy1(Units.toEMU(lineMarginTopAndBottomInPt));
  anchor.setDy2(Units.toEMU(lineMarginTopAndBottomInPt));
  //draw a line positioned by the anchor.
  drawLine((XSSFDrawing)drawing, (XSSFClientAnchor)anchor);
  
  anchor = getAnchorHorizontalFromCell(helper, cell);
  anchor.setDy1(Units.toEMU(rowHeightInPt-lineMarginTopAndBottomInPt));
  anchor.setDy2(Units.toEMU(rowHeightInPt-lineMarginTopAndBottomInPt));
  drawLine((XSSFDrawing)drawing, (XSSFClientAnchor)anchor);
  
  FileOutputStream out = new FileOutputStream(filePath);
  workbook.write(out);
  out.close();
  workbook.close();

 }
}