POI Excel 上下標處理(sub,sup的HTML標簽轉(zhuǎn)化到excel格式)

用Apache POI把文字信息輸出到Excel的時候续室,遇到如圖的情況摇零。HTML中這些上標下標是用‘<sup></sup>历帚,<sub></sub>’包起來的

那么要導出到excel锋恬,如何讓excel里面也顯示如圖的樣子屯换,而不是直接顯示那些標簽呢?

sup
sub

話不多說与学,先導包:

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.16</version>
        </dependency>

核心的代碼就是:

String content="aaa<sub>2</sub>ccc"
//生成workbook
HSSFWorkbook workbook = new HSSFWorkbook();
//生成sheet
HSSFSheet sheet = workbook.createSheet("sheet1");
//生成行row(第一行)
HSSFRow row = sheet.createRow(0);
//創(chuàng)建單元格(第一行第一格)
HSSFCell cell = row.createCell(0);
//生成富文本文字
HSSFRichTextString text = new HSSFRichTextString(content);
//生成字體
HSSFFont  ft = workbook.createFont();
//設(shè)置下標字體趟径,sup的話此處設(shè)置HSSFFont.SS_SUPER
ft.setTypeOffset(HSSFFont.SS_SUB);
//設(shè)置字體生效的位置區(qū)間,content字符串去掉sub標簽之后癣防,第四個字符需要處理成下標,所以參數(shù)是3掌眠,4
//如果是content="aaa<sub>23</sub>ccc",位置參數(shù)就是3蕾盯,5,不同位置可多次調(diào)用applyFont方法
text.applyFont(3,4,ft);
cell.setCellValue(text);
//TODO 輸出文件
......

了解核心代碼之后蓝丙,需要做的就是解析字符串中的標簽级遭,然后按照這個方法處理。以下是我寫的比較完整的解析例子渺尘。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExcelUtils2 {
    private static final String SUB_START = "<sub>";
    private static final String SUB_END = "</sub>";
    private static final String SUP_START = "<sup>";
    private static final String SUP_END = "</sup>";

    public static void main(String[] args) {
        String title = "一種F<sup>-</sup>挫鸽、Zn<sup>2+</sup>、B<sup>3+</sup>離子協(xié)同摻雜電解質(zhì),H<sub>2</sub>O是水";

        List<List<int[]>> tagIndexArr = null;
        if (containSubSup(title)) {
            tagIndexArr = new ArrayList<List<int[]>>();
            title = getSubSupIndexs(title, tagIndexArr);
        }
        //TODO 文件路徑自己改
        File f = new File("C:\\tmp\\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);
                    for (int[] pair : sups) {
                        text.applyFont(pair[0], pair[1], ft);
                    }
                }
                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盔沫,第二個元素是結(jié)束標簽的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標簽的開始和對應的結(jié)束的標簽的index干茉,方便后面根據(jù)這個標簽做字體操作
     * @param s
     * @param tagIndexList 傳一個新建的空list進來谴忧,方法結(jié)束的時候會存儲好標簽位置信息。
     * <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[] sub_pair = getNextSubsTagsIndex(s, SUB_START);
            int[] sup_pair = getNextSubsTagsIndex(s, SUP_START);
            boolean subFirst = true;
            boolean supFirst = true;
            if(sub_pair != null && sup_pair != null) {
                //兩種標簽都存在的時候要考慮到誰在前沾谓,在前的標簽優(yōu)先處理
                //因為如果在后的標簽處理完,index就定下來戳鹅,再處理在前的均驶,后面的index就會產(chǎn)生偏移量。從前開始處理不會存在這個問題
                if(sub_pair[0] < sup_pair[0]) {
                    supFirst = false;
                } else {
                    subFirst = false;
                }
            }
            if (sub_pair != null && subFirst) {
                s = removeNextSubTags(s, SUB_START);
                //<sub>標簽被去掉之后粉楚,結(jié)束標簽需要相應往前移動
                sub_pair[1] = sub_pair[1] - SUB_START.length();
                subs.add(sub_pair);
                continue;
            }
            if (sup_pair != null && supFirst) {
                s = removeNextSubTags(s, SUP_START);
                //<sup>標簽被去掉之后辣恋,結(jié)束標簽需要相應往前移動
                sup_pair[1] = sup_pair[1] - SUP_START.length();
                sups.add(sup_pair);
                continue;
            }
            if (sub_pair == null && sup_pair == null) {
                break;
            }
        }

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

}

OJBK!DH怼伟骨!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市燃异,隨后出現(xiàn)的幾起案子携狭,更是在濱河造成了極大的恐慌,老刑警劉巖回俐,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逛腿,死亡現(xiàn)場離奇詭異,居然都是意外死亡仅颇,警方通過查閱死者的電腦和手機单默,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忘瓦,“玉大人搁廓,你說我怎么就攤上這事「ぃ” “怎么了境蜕?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長凌停。 經(jīng)常有香客問我粱年,道長,這世上最難降的妖魔是什么罚拟? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任台诗,我火速辦了婚禮完箩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拉庶。我一直安慰自己嗜憔,他們只是感情好,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布氏仗。 她就那樣靜靜地躺著吉捶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪皆尔。 梳的紋絲不亂的頭發(fā)上呐舔,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音慷蠕,去河邊找鬼珊拼。 笑死,一個胖子當著我的面吹牛流炕,可吹牛的內(nèi)容都是我干的澎现。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼每辟,長吁一口氣:“原來是場噩夢啊……” “哼剑辫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起渠欺,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤妹蔽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后挠将,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胳岂,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年舔稀,在試婚紗的時候發(fā)現(xiàn)自己被綠了乳丰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡内贮,死狀恐怖成艘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贺归,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布断箫,位于F島的核電站拂酣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仲义。R本人自食惡果不足惜婶熬,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一剑勾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赵颅,春花似錦虽另、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至募寨,卻和暖如春族展,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拔鹰。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工仪缸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人列肢。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓恰画,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瓷马。 傳聞我的和親對象是個殘疾皇子拴还,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容