POI Excel转word 单元格部分下标及单元格内容居中 POI读数浮点型问题解决

excel转word 专栏收录该内容
1 篇文章 0 订阅

POI Excel转word 单元格部分下标及单元格内容居中 POI读数浮点型问题解决

  • 本文章只做记录,这次需求比较特殊,大家具体情况和需求具体解决
  • xlsx转docx

  • 由于项目需求,对Excel转word有比较特殊的要求,尝试了aspose、pageoffice、都不能满足自身需求,问题主要集中在两个方面
    • 转换后数值数据要和原Excel一致
    • 转换后word表格要居中,单元格要可部分下标和斜体
  • aspose接口可以做到数值数据与原excel看到的一致,但是无法做到单元格内数据部分下标部分斜体(也可能是我文档接口没看到)
  • pageoffice可在空白word直接插入excel,但插入为Excel对象格式无法分页
  • POI接口读取数值类型返回浮点型,总是出现与原excel数值不一致情况(1读成1.0,公式就更离谱),excel公式得出的数值BigDecimal转换后会有丢失,依旧不行。
  • 结论:
    • 利用aspose读取Excel数值
    • 利用POI读取单元格并获取字体格式在Word中设置
    • 最后利用pageoffice在书签处插入生成的word

读取Excel单元格,设置word表格中字体

  • 先判断单元格类型,为STRING类型的才需要设置斜体和下标等
//设置字体格式,斜体或下标,以及赋值(word表格)
public static void setCellFont(XSSFSheet sheet,XSSFCell cell,XWPFTableCell tableCell,String cellValue){
    Integer width = sheet.getColumnWidth(cell.getColumnIndex());
    setCellWandVAL(tableCell,width.toString(),STVerticalJc.CENTER,STJc.CENTER);
    XWPFParagraph cellParagraph = tableCell.getParagraphArray(0);
    CellType cellType = cell.getCellType();
    // 判断数据的类型
    switch (cellType){
        case STRING:
        //String类型
        XSSFRichTextString richTextString = cell.getRichStringCellValue();
        //每读一个字,判断一次字体是否是斜体,以及是否是上下标,一个一个设置样式
        for (int p = 0; p < richTextString.length(); p++) {
            //遍历文体,判断字体格式(上下标和斜体)
            XWPFRun cellParagraphRun = cellParagraph.createRun();//开始新的标记
            XSSFFont font = richTextString.getFontAtIndex(p);
            if(font==null){
                //有些字体类型会为空
                cellParagraphRun.setText(cellValue.substring(p,p+1));
                continue;
            }
            boolean italic = font.getItalic();//斜体
            short offset = font.getTypeOffset();//上下标
            cellParagraphRun.setItalic(italic);
            if(offset==XSSFFont.SS_SUPER){//上标
                cellParagraphRun.setSubscript(VerticalAlign.SUPERSCRIPT);
            }
            if(offset==XSSFFont.SS_SUB){//下标
                cellParagraphRun.setSubscript(VerticalAlign.SUBSCRIPT);
            }
            cellParagraphRun.setText(cellValue.substring(p,p+1));
        }
        break;
    default:
        //非String类型
        XSSFCellStyle cellStyle = cell.getCellStyle();
        XSSFFont font = cellStyle.getFont();
        Boolean italic = font.getItalic();
        XWPFRun cellParagraphRun = cellParagraph.createRun();
        cellParagraphRun.setItalic(italic);
        cellParagraphRun.setText(cellValue);
        break;
    }

}

设置单元格宽度以及文本居中,上下居中

//设置表格宽,字体居中和垂直格式
public static void setCellWandVAL(XWPFTableCell cell,String width,STVerticalJc.Enum typeEnum, STJc.Enum vAlign){
    CTTc ctTc = cell.getCTTc();
    CTTcPr ctTcPr = ctTc.addNewTcPr();
    ctTcPr.addNewVAlign().setVal(typeEnum);
    ctTc.getPList().get(0).addNewPPr().addNewJc().setVal(vAlign);
    cell.setWidth(width);
}

合并单元格

//合并指定区域的单元格
public static XWPFTable tableMerge(XWPFTable table,XSSFSheet sheet,int startRow,int endRow){
    //合并word中的单元格
    int sheetMergeCount = sheet.getNumMergedRegions();
    for (int i = 0; i < sheetMergeCount; i++) {
        CellRangeAddress range = sheet.getMergedRegion(i);
        int firstColumn = range.getFirstColumn();
        int lastColumn = range.getLastColumn();
        int firstRow = range.getFirstRow();
        int lastRow = range.getLastRow();
        if(firstRow>=startRow&&lastRow<=endRow){
            if(startRow!=0){
                firstRow = firstRow - startRow;
                lastRow = lastRow - startRow;
            }
            for(int Row=firstRow;Row<=lastRow;Row++){
                mergeCellsHorizontal(table,Row,firstColumn,lastColumn);
            }
            mergeCellsVertically(table,firstColumn,firstRow,lastRow);
        }

    }
    return table;
}

// word跨列合并单元格
public  static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
    for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
        XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
        if ( cellIndex == fromCell ) {
            // The first merged cell is set with RESTART merge value
            cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
        } else {
            // Cells which join (merge) the first one, are set with CONTINUE
            cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
        }
    }
}
// word跨行并单元格
public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
    for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
        XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
        if ( rowIndex == fromRow ) {
            // The first merged cell is set with RESTART merge value
            cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
        } else {
            // Cells which join (merge) the first one, are set with CONTINUE
            cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
        }
    }
}

最终效果

  • excel
    在这里插入图片描述
  • word
    在这里插入图片描述
  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

Jason·

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值