Apache POI печать проблемы формы линии - PullRequest
0 голосов
/ 08 января 2020

Мне нужна ваша помощь, у меня есть код (см. Ниже), который добавляет формы линий со стрелками в ячейку в Excel, используя Apache POI в Java. Смотри мой код. но после экспорта, затем открыв Excel это сообщение из диалогового окна, выдает «Рисование из /xl/drawings/drawing3.xml part (Drawing shape)». Пожалуйста, смотрите скриншот.

// create workbook
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet( "Node" );
CreationHelper helper = wb.getCreationHelper();
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = helper.createClientAnchor();

//anchor from
//parent
anchor.setCol1( gParentCell.getColumnIndex() + 1 );
anchor.setRow1( gParentCell.getRowIndex() );

anchor.setDy1( Units.toEMU( 7.2 ) );

//anchor to
//child
anchor.setCol2( this.col );
anchor.setRow2( this.row );

anchor.setDy2( Units.toEMU( 7.2 ) );

XSSFSimpleShape shape = ((XSSFDrawing)drawing).createSimpleShape((XSSFClientAnchor)anchor);
shape.setShapeType( ShapeTypes.LINE );
shape.setLineWidth(1);
shape.setLineStyle(0);

// draw the arrow
CTShapeProperties shapeProperties = shape.getCTShape().getSpPr();

CTLineEndProperties lineEndProperties = org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties.Factory.newInstance();
lineEndProperties.setType(STLineEndType.TRIANGLE);

// print arrow
CTLineProperties lineProperties = shapeProperties.getLn();
lineProperties.setTailEnd(lineEndProperties);

Excel пытается восстановить

ошибка

Выход

Ответы [ 2 ]

1 голос
/ 08 января 2020

В привязке индекс 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();

 }
}

Результат:

enter image description here

0 голосов
/ 08 января 2020

Я хочу поделиться с тем, что я только что узнал,

Это правильно shape.getCTShape (). GetSpPr (). GetXfrm (). SetFlipV (true);

Но вы также можно использовать ShapeTypes.LINE_INV;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...