美文网首页
POI实现上标下标和单元格部分样式修改

POI实现上标下标和单元格部分样式修改

作者: 境与界 | 来源:发表于2019-12-31 17:55 被阅读0次

本文大部分内容来自 https://www.jianshu.com/p/9106c8472d3b
他实现了上标下标 。

为啥还要写这个呢?
因为有上标下标的单元格 有些字体的样式没有变,所以有了部分样式修改。

  • 核心代码

text.applyFont()用这个api 对不同位置的字体用不同的样式即可。

                    // 上标
                    HSSFFont ft = workbook.createFont();
                    ft.setTypeOffset(HSSFFont.SS_SUPER);
                    // 加粗
                    HSSFFont font = workbook.createFont();
                    font.setBold(true);
                    font.setFontHeightInPoints((short) 10);
                    for (int[] pair : sups) {
                        text.applyFont(pair[0], pair[1], ft);
                        text.applyFont(pair[1], title.length(), font);
                    }
  • 例子


    image.png
 public static void main(String[] args) {
        String title = "一种F<sup>-</sup>、Zn<sup>2+</sup>、B<sup>3+</sup>离子协同掺杂电解质,H<sub>2</sub>O是水";

        List<List<int[]>> tagIndexArr = null;
        if (containSubSup(title)) {
            tagIndexArr = new ArrayList<>();
            title = getSubSupIndexs(title, tagIndexArr);
        }
        //TODO 文件路径自己改
        File f = new File("C:test.xls");
        try {
            FileOutputStream fout = new FileOutputStream(f);
            // 声明一个工作薄
            @SuppressWarnings("resource")
            HSSFWorkbook workbook = new HSSFWorkbook();
            // 生成一个表格
            HSSFSheet sheet = workbook.createSheet("sheet1");
            int curRowIndex = 0;
            HSSFRow row = sheet.createRow(curRowIndex);
            HSSFCell cell = row.createCell(0);

            if (tagIndexArr != null) {
                HSSFRichTextString text = new HSSFRichTextString(title);
                List<int[]> subs = tagIndexArr.get(0);
                List<int[]> sups = tagIndexArr.get(1);
                if (subs.size() > 0) {
                    HSSFFont ft = workbook.createFont();
                    ft.setTypeOffset(HSSFFont.SS_SUB);
                    for (int[] pair : subs) {
                        text.applyFont(pair[0], pair[1], ft);
                    }
                }
                if (sups.size() > 0) {
                    // 上标
                    HSSFFont ft = workbook.createFont();
                    ft.setTypeOffset(HSSFFont.SS_SUPER);
                    // 加粗
                    HSSFFont font = workbook.createFont();
                    font.setBold(true);
                    font.setFontHeightInPoints((short) 10);
                    for (int[] pair : sups) {
                        text.applyFont(pair[0], pair[1], ft);
                        text.applyFont(pair[1], title.length(), font);
                    }
                }
                cell.setCellValue(text);
            } else {
                cell.setCellValue(title);
            }

            try {
                workbook.write(fout);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 获取下一对标签的index,不存在这些标签就返回null
     * @param s
     * @param tag SUB_START 或者SUP_START
     * @return int[]中有两个元素,第一个是开始标签的index,第二个元素是结束标签的index
     */
    private static int[] getNextSubsTagsIndex(String s, String tag) {

        int firstSubStart = s.indexOf(tag);
        if (firstSubStart > -1) {
            int firstSubEnd = s.indexOf(tag.equals(SUB_START) ? SUB_END : SUP_END);
            if (firstSubEnd > firstSubStart) {
                return new int[] { firstSubStart, firstSubEnd };
            }
        }
        return null;
    }

    /**移除下一对sub或者sup标签,返回移除后的字符串
     * @param s
     * @param tag SUB_START 或者SUP_START
     * @return
     */
    private static String removeNextSubTags(String s, String tag) {
        s = s.replaceFirst(tag, "");
        s = s.replaceFirst(tag.equals(SUB_START) ? SUB_END : SUP_END, "");
        return s;
    }

    /**
     * 判断是不是包含sub,sup标签
     * @param s
     * @return
     */
    private static boolean containSubSup(String s) {
        return (s.contains(SUB_START) && s.contains(SUB_END)) || (s.contains(SUP_START) && s.contains(SUP_END));
    }

    /**
     * 处理字符串,得到每个sub,sup标签的开始和对应的结束的标签的index,方便后面根据这个标签做字体操作
     * @param s
     * @param tagIndexList 传一个新建的空list进来,方法结束的时候会存储好标签位置信息。
     * <br>tagIndexList.get(0)存放的sub
     * <br>tagIndexList.get(1)存放的是sup
     *
     * @return 返回sub,sup处理完之后的字符串
     */
    private static String getSubSupIndexs(String s, List<List<int[]>> tagIndexList) {
        List<int[]> subs = new ArrayList<int[]>();
        List<int[]> sups = new ArrayList<int[]>();

        while (true) {
            int[] subPair = getNextSubsTagsIndex(s, SUB_START);
            int[] supPair = getNextSubsTagsIndex(s, SUP_START);
            boolean subFirst = true;
            boolean supFirst = true;
            if(subPair != null && supPair != null) {
                //两种标签都存在的时候要考虑到谁在前,在前的标签优先处理
                //因为如果在后的标签处理完,index就定下来,再处理在前的,后面的index就会产生偏移量。从前开始处理不会存在这个问题
                if(subPair[0] < supPair[0]) {
                    supFirst = false;
                } else {
                    subFirst = false;
                }
            }
            if (subPair != null && subFirst) {
                s = removeNextSubTags(s, SUB_START);
                //<sub>标签被去掉之后,结束标签需要相应往前移动
                subPair[1] = subPair[1] - SUB_START.length();
                subs.add(subPair);
                continue;
            }
            if (supPair != null) {
                s = removeNextSubTags(s, SUP_START);
                //<sup>标签被去掉之后,结束标签需要相应往前移动
                supPair[1] = supPair[1] - SUP_START.length();
                sups.add(supPair);
                continue;
            }
            break;
        }

        tagIndexList.add(subs);
        tagIndexList.add(sups);
        return s;
    }

相关文章

网友评论

      本文标题:POI实现上标下标和单元格部分样式修改

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