美文网首页
Java中使用POI在Excel单元格中画斜线—XLSX格式

Java中使用POI在Excel单元格中画斜线—XLSX格式

作者: 通靈鹿小六 | 来源:发表于2021-01-29 14:40 被阅读0次

    在前面介绍过如何在XLS格式的Excel中画斜线。
    Java中使用POI在Excel单元格中画斜线—XLS格式

    本章节介绍一下,在XLSX格式的Excel中画斜线的方法。

    1、初始化XSSFWorkbook对象

    初始化XSSFWorkbook对象,创建两行两列单元格,分别设置行高和列宽以及单元格的边框。

    /**
     * @Author 通靈鹿小六
     * @Description 模拟测试使用的XSSFWorkbook对象
     * @Date 2021-01-27 17:23
     * @return org.apache.poi.xssf.usermodel.XSSFWorkbook
     **/
    private XSSFWorkbook getTestXSSFWorkbook() {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet("line");
        XSSFRow row0 = sheet.createRow(0);
        row0.setHeightInPoints(100);
        XSSFRow row1 = sheet.createRow(1);
        row1.setHeightInPoints(70);
    
        XSSFCellStyle cellStyle = getCellFormat(wb);
    
        sheet.setColumnWidth(0, 80 * 90);
        sheet.setColumnWidth(1, 60 * 90);
        XSSFCell cell0_0 = row0.createCell(0);
        XSSFCell cell0_1 = row0.createCell(1);
        XSSFCell cell1_0 = row1.createCell(0);
        XSSFCell cell1_1 = row1.createCell(1);
        cell0_0.setCellStyle(cellStyle);
        cell0_1.setCellStyle(cellStyle);
        cell1_0.setCellStyle(cellStyle);
        cell1_1.setCellStyle(cellStyle);
    
        return wb;
    }
    
    private XSSFCellStyle getCellFormat(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        if (cellStyle.getBorderBottom() != BorderStyle.THIN) {
            cellStyle.setBorderBottom(BorderStyle.THIN);
        }
        if (cellStyle.getBorderLeft() != BorderStyle.THIN) {
            cellStyle.setBorderLeft(BorderStyle.THIN);
        }
        if (cellStyle.getBorderTop() != BorderStyle.THIN) {
            cellStyle.setBorderTop(BorderStyle.THIN);
        }
        if (cellStyle.getBorderRight() != BorderStyle.THIN) {
            cellStyle.setBorderRight(BorderStyle.THIN);
        }
        cellStyle.setBottomBorderColor((short) 0);
        cellStyle.setLeftBorderColor((short) 0);
        cellStyle.setRightBorderColor((short) 0);
        cellStyle.setTopBorderColor((short) 0);
    
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    
        XSSFFont xssfFont = wb.createFont();
        xssfFont.setFontName("Arial");
        cellStyle.setFont(xssfFont);
    
        return cellStyle;
    }
    

    2、在Cell中画斜线

    注意:在XLSX格式的单元格中画线的时候,是不支持从下往上画的。换个说法,斜线的终止点坐标X必须大于等于起始点坐标X,终止点坐标Y必须大于等于起始点坐标Y。如下图所示两种情况,是需要特殊处理的。:

    /**
     * @Author 通靈鹿小六
     * @Description 在XLSX文件中画斜线
     * @Date 2021-01-27 16:34
     * @param sheet XSSFSheet格式对象
     * @param rowIndex 斜线表头单元格行索引
     * @param colIndex 斜线表头单元格列索引
     * @param slashType 斜线类型
     * @param slpList 斜线表头线集合
     **/
    private static void drawLineXlsx(XSSFSheet sheet, int rowIndex, int colIndex, String slashType, ArrayList<SlashLinePosition> slpList) {
        XSSFDrawing xssfDrawing = sheet.createDrawingPatriarch();
    
        for (SlashLinePosition slp : slpList) {
            XSSFClientAnchor xssfClientAnchor = new XSSFClientAnchor(
                    slp.getStartX(), slp.getStartY(), slp.getEndX(), slp.getEndY(),
                    colIndex, rowIndex, colIndex, rowIndex);
            XSSFSimpleShape shape = xssfDrawing.createSimpleShape(xssfClientAnchor);
    
            if (slashType == "LEFT_TOP" || slashType == "RIGHT_BOTTOM") {
                //斜线类型为左上,右下的时候,使用斜线
                shape.setShapeType(ShapeTypes.LINE);
            } else {
                //斜线类型为左下,右上的时候,使用反斜线
                shape.setShapeType(ShapeTypes.LINE_INV);
            }
            // 设置线宽
            shape.setLineWidth(0.5);
            // 设置线的风格
            shape.setLineStyle(0);
            // 设置线的颜色
            shape.setLineStyleColor(0, 0, 0);
        }
    }
    

    如果我们想画如下一条斜线:

    图1

    上面说了,不能从下往上画线。所以要使用反斜线。而在使用反斜线的同时,线条的坐标也要发生变化。

    最终定义如图2所示的坐标,同时设置线条为反斜线,最终生成的单元格效果和图1一样。

    图2

    3、计算线的坐标

    结合第二点中介绍的内容,当斜线类型为LEFT_BOTTOM和RIGHT_TOP的时候,计算线的起止坐标也会有不一样。最终代码如下:

    /**
     * @Author 通靈鹿小六
     * @Description 获取斜线表头斜线开始结束位置坐标对象集合
     * @Date 2021-01-27 8:39
     * @param slashType 斜线类型 LEFT_TOP左上角为起点 LEFT_BOTTOM左下角为起点 RIGHT_TOP右上角为起点 RIGHT_BOTTOM右下角为起点
     * @param slashCount 斜线数量
     * @param xssfSheet XLSX格式sheet对象
     * @param rowIndex 斜线表头单元格行索引
     * @param colIndex 斜线表头单元格列索引
     * @return java.util.ArrayList<com.goldwind.gwngspr.core.definition.SlashLinePosition> 位置坐标对象集合
     **/
    private static ArrayList<SlashLinePosition> getSlashLinePositionXlsx(String slashType, int slashCount, XSSFSheet xssfSheet, int rowIndex, int colIndex) {
        ArrayList<SlashLinePosition> slpList = new ArrayList<>();
        int width = xssfSheet.getColumnWidth(colIndex) * 300;
        int height = xssfSheet.getRow(rowIndex).getHeight() * 700;
    
        switch (slashType) {
            case "LEFT_TOP":
                if (slashCount == 2) {
                    //表示只有一条斜线
                    SlashLinePosition slp = new SlashLinePosition(0, 0, width, height);
                    slpList.add(slp);
                } else if (slashCount == 3) {
                    //表示有两条斜线
                    SlashLinePosition slp1 = new SlashLinePosition(0, 0, width / 2, height);
                    slpList.add(slp1);
                    SlashLinePosition slp2 = new SlashLinePosition(0, 0, width, height / 2);
                    slpList.add(slp2);
                }
                break;
            case "LEFT_BOTTOM":
                if (slashCount == 2) {
                    //表示只有一条斜线
                    SlashLinePosition slp = new SlashLinePosition(0, 0, width, height);
                    slpList.add(slp);
                } else if (slashCount == 3) {
                    //表示有两条斜线
                    SlashLinePosition slp1 = new SlashLinePosition(0, 0, width / 2, height);
                    slpList.add(slp1);
                    SlashLinePosition slp2 = new SlashLinePosition(0, height / 2, width, height);
                    slpList.add(slp2);
                }
                break;
            case "RIGHT_TOP":
                if (slashCount == 2) {
                    //表示只有一条斜线
                    SlashLinePosition slp = new SlashLinePosition(0, 0, width, height);
                    slpList.add(slp);
                } else if (slashCount == 3) {
                    //表示有两条斜线
                    SlashLinePosition slp1 = new SlashLinePosition(0, 0, width, height / 2);
                    slpList.add(slp1);
                    SlashLinePosition slp2 = new SlashLinePosition(width / 2, 0, width, height);
                    slpList.add(slp2);
                }
                break;
            case "RIGHT_BOTTOM":
                if (slashCount == 2) {
                    //表示只有一条斜线
                    SlashLinePosition slp = new SlashLinePosition(0, 0, width, height);
                    slpList.add(slp);
                } else if (slashCount == 3) {
                    //表示有两条斜线
                    SlashLinePosition slp1 = new SlashLinePosition(0, height / 2, width, height);
                    slpList.add(slp1);
                    SlashLinePosition slp2 = new SlashLinePosition(width / 2, 0, width, height);
                    slpList.add(slp2);
                }
                break;
            default:
                break;
        }
    
        return slpList;
    }
    

    代码中,定义width和heigth的时候,分别乘以了不同的系数。系数是我测试出来的,但是没有弄清楚为何这样子,如果有明白的人可以告诉我一下。

    int width = xssfSheet.getColumnWidth(colIndex) * 300;
    int height = xssfSheet.getRow(rowIndex).getHeight() * 700;

    最终生成的效果如下图所示:

    如果本文对您有了启发作用,请动动小手,麻烦点个赞~~

    相关文章

      网友评论

          本文标题:Java中使用POI在Excel单元格中画斜线—XLSX格式

          本文链接:https://www.haomeiwen.com/subject/truqtltx.html