Apache POI XSSF无法创建向上箭头

时间:2017-04-05 14:53:05

标签: apache apache-poi xssf

我正在使用Apache POI处理Excel生成的文件。该文件必须是xlsx而不是xls。 我需要画一些箭,但是我不能画一个向上的箭。 我使用XSSFClientAnchor创建我的箭头并指定row / col 1和row / col 2。

XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2)

仅当col 1>时才有效。第2栏和第1行>第2行。所以我不能画一个向上的箭头。 如果我尝试更改值以获得向上箭头,则Excel生成的文件无法读取。 Excel修复它,但箭头被隐藏。

这是我的代码:

public static void test() {
    XSSFWorkbook wb = new XSSFWorkbook();
    XSSFSheet sheet = wb.createSheet("linechart");
    XSSFDrawing pat = sheet.createDrawingPatriarch();

    XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 10, 10, 5, 5);

    XSSFSimpleShape shape = pat.createSimpleShape(anchor);
    shape.setShapeType(ShapeTypes.LINE);
    shape.setLineWidth(4);
    shape.setLineStyle(0);
    shape.setLineStyleColor(0, 0, 0);

    FileOutputStream fileOut;
    try {
        fileOut = new FileOutputStream(
                "C:\\monfichier" + new Date().toString().replace(':', '_') + ".xlsx");
        wb.write(fileOut);
        fileOut.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

如果我尝试替换:

XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 10, 10, 5, 5);

使用:

XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 5, 5, 10, 10);

没关系......

你能测试一下这个并告诉我你对此有何看法?很难找到有关POI的信息,我也没有发现这个问题...

1 个答案:

答案 0 :(得分:2)

锚点决定了形状的大小。对于线形,该线默认从第一个锚单元的左上边缘到左上边缘加上最后一个锚单元的dxdy。第一锚单元是锚的左上方的单元,而最后的锚单元是锚的右下方的单元。因此,默认情况下,线条形状将从左上角到右下角。

如果我们希望它从左下角到右上角,那么我们必须翻转形状。

如果我们在Excel中从左下角到右上角绘制一条线,然后查看存储的/xl/drawings/drawing1.xml,我们会看到此手动绘制的线条形状也会翻转。

两行示例:

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

import java.io.FileOutputStream;

class CreateExcelLineShapes {

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

  Workbook workbook = new XSSFWorkbook();
  Sheet sheet = workbook.createSheet("Sheet1");

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

  ClientAnchor anchor = helper.createClientAnchor();

  //Anchor B2:C4
  //This determines the size of the line shape to be from 
  //upper left edge of B2 to upper left edge of C4 plus dx and dy.
  //Since dx and dy are both 0, this is the bottom right edge of B3.
  anchor.setCol1(1);
  anchor.setRow1(1); 
  anchor.setCol2(2);
  anchor.setRow2(3);

  //From here on XSSF only.
  XSSFDrawing xssfdrawing = (XSSFDrawing)drawing;
  XSSFClientAnchor xssfanchor = (XSSFClientAnchor)anchor;

  //Draw a line from upper left edge of B2 to upper left edge of C4 = bottom right edge of B3.
  //This is the default.
  XSSFSimpleShape xssfshape = xssfdrawing.createSimpleShape(xssfanchor);
  xssfshape.setShapeType(ShapeTypes.LINE);
  xssfshape.setLineWidth(4);
  xssfshape.setLineStyle(0);
  xssfshape.setLineStyleColor(0, 0, 0);

  //This sets the arrow line end type:
  xssfshape.getCTShape().getSpPr().getLn().addNewTailEnd().setType(
    org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType.TRIANGLE);

  //Again draw a line from upper left edge of B2 to upper left edge of C4 = bottom right edge of B3.
  xssfshape = xssfdrawing.createSimpleShape(xssfanchor);
  xssfshape.setShapeType(ShapeTypes.LINE);
  xssfshape.setLineWidth(4);
  xssfshape.setLineStyle(0);
  xssfshape.setLineStyleColor(0, 0, 0);

  //Now flip this vertically.
  //So it now will to be from bottom left edge of B3 to upper left edge of B2.
  xssfshape.getCTShape().getSpPr().getXfrm().setFlipV(true);

  xssfshape.getCTShape().getSpPr().getLn().addNewTailEnd().setType(
    org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType.TRIANGLE);

  workbook.write(new FileOutputStream("CreateExcelLineShapes.xlsx"));
  workbook.close();

 }
}

结果:

enter image description here