最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA實(shí)現(xiàn)Excel和PDF上下標(biāo)的操作代碼

 更新時(shí)間:2023年09月25日 11:16:49   作者:拾荒的小海螺  
這篇文章主要介紹了JAVA實(shí)現(xiàn)Excel和PDF上下標(biāo),本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

1、簡介

最近項(xiàng)目需要實(shí)現(xiàn)26個(gè)小寫字母的上下標(biāo)功能,自己去網(wǎng)上找了所有Unicode的上下標(biāo)形式,缺少一些關(guān)鍵字母,顧后面考慮自己創(chuàng)建上下標(biāo)字體樣式,以此來記錄。

2、Excel

Excel本身是支持上下標(biāo),我們可以通過Excel單元格的樣式來設(shè)置當(dāng)前字體上下標(biāo),因使用的是POI的maven包,這邊就以POI的樣例實(shí)現(xiàn)。

首先pom.xml引用:

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

實(shí)現(xiàn)上下標(biāo)代碼:

XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Sheet1");
XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell(0);
XSSFFont font = workbook.createFont();
font.setTypeOffset(XSSFFont.SS_SUB); // 上標(biāo)
font.setTypeOffset(XSSFFont.SS_SUPER);//下標(biāo)
XSSFRichTextString richTextString = new XSSFRichTextString("Hcu");
richTextString.applyFont(1, 2, font); // 設(shè)置第二個(gè)字符為上標(biāo) "c"
richTextString.applyFont(2, 3, font); // 設(shè)置第三個(gè)字符為下標(biāo) "u"
cell.setCellValue(richTextString);
Path tempFile =  Paths.get("E:\\dist\\pdf0.xlsx");
try(OutputStream os = Files.newOutputStream(tempFile)){
	workbook.write(os);
	logger.error("xssfWorkbook-end:" + tempFile.toAbsolutePath());
}

3、造字

因某些字母沒有對(duì)應(yīng)的上下標(biāo)字形,所以通過FontCreate軟件來造上下標(biāo),至于軟件可以去網(wǎng)上下載破解版,還有就是Unicode指定的數(shù)量就那么多,所以我們可以通過改變已有Unicode編碼字符來作為我們上下標(biāo)的編碼。

可以通過找到當(dāng)前分支少的Unicode字符做插入:比如選中西里爾字母這個(gè)分類點(diǎn)擊 插入->字符:

在這里插入圖片描述

然后我們對(duì)已有的字符做修改和做刪除自己造:

在這里插入圖片描述

最后形成我們自己所需要的字符:

在這里插入圖片描述

4、PDF

生成的PDF,采用開源的是開放源碼的站點(diǎn)sourceforge一個(gè)項(xiàng)目itextpdf,是用于生成PDF文檔的一個(gè)java類庫。通過iText不僅可以生成PDF或rtf的文檔,而且可以將XML、Html文件轉(zhuǎn)化為PDF文件。因項(xiàng)目通過Excel來轉(zhuǎn)PDF,但是因itextpdf無法識(shí)別Excel上下標(biāo),并且缺少了關(guān)鍵上下標(biāo)。

首先pom.xml引用:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.10</version>
</dependency>

輸出中文,還要引入下面itext-asian.jar包:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>

通過以上造好的字母上下標(biāo),直接通過加載指定的Unicode來實(shí)現(xiàn)實(shí)現(xiàn)加載:

String value = "設(shè)計(jì)強(qiáng)度?\u0460\u0461";
File pdfFile = new File("E:\\dist\\pdf1.pdf");
//字符和Unicode組合格式化
value = StringEscapeUtils.unescapeJava(value);
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdfFile));
document.open();
// 將 Excel 單元格內(nèi)容寫入 PDF 文檔
PdfPTable table = new PdfPTable(1);
BaseFont bf = BaseFont.createFont("E:\\cell\\Merge.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
com.itextpdf.text.Font  f = new com.itextpdf.text.Font(bf, 10);
Paragraph p = new Paragraph(value, f);
table.addCell(p);
document.add(table);
document.close();
writer.close();

5、字符映射

因設(shè)計(jì)可以通過造字來實(shí)現(xiàn)上下標(biāo)字母,現(xiàn)在我們可以通過指定字符來實(shí)現(xiàn)當(dāng)前上下標(biāo)的標(biāo)簽替換,設(shè)計(jì)上下標(biāo)通過標(biāo)簽來包裹,類似:下標(biāo):<sub> </sub> 上標(biāo):<sup><sup>來標(biāo)簽指定上下標(biāo)。
通過解析當(dāng)前字符串上下標(biāo)標(biāo)簽來實(shí)現(xiàn)字符替換:

private static final String SUB_START = "<sub>";	//下標(biāo)
private static final String SUB_END = "</sub>";
private static final String SUP_START = "<sup>";	//上標(biāo)
private static final String SUP_END = "</sup>";
/**
 * 獲取下一對(duì)標(biāo)簽的index,不存在這些標(biāo)簽就返回null
 * @param s
 * @param tag SUB_START或者SUP_START
 * @return int[]中有兩個(gè)元素,第一個(gè)是開始標(biāo)簽的index,第二個(gè)元素是結(jié)束標(biāo)簽的index
 */
public static int[] getNextTagsIndex(String s, String tag) {
    int firstStart = s.indexOf(tag);
    if (firstStart > -1) {
        int firstEnd = 0;
        if (tag.equals(SUB_START)) {
            firstEnd = s.indexOf(SUB_END);
            String ssString = s.substring(firstStart, firstEnd+SUB_END.length());
            if (ssString.contains(SUP_START)) {
                ssString = ssString.replace(SUP_START, "").replaceAll(SUP_END, "");
                firstEnd = firstStart + ssString.indexOf(SUB_END);
            }
        }else if (tag.equals(SUP_START)) {
            firstEnd = s.indexOf(SUP_END);
            String ssString = s.substring(firstStart, firstEnd+SUP_END.length());
            if (ssString.contains(SUB_START)) {
                ssString = ssString.replace(SUP_START, "").replaceAll(SUP_END, "");
                firstEnd = firstStart + ssString.indexOf(SUP_END);
            }
        }
        if (firstEnd > firstStart) {
            return new int[] { firstStart, firstEnd };
        }
    }
    return null;
}
/**移除下一對(duì)sub或者sup標(biāo)簽,返回移除后的字符串
 * @param s
 * @param tag SUB_START或者SUP_START
 * @return
 */
public static String removeNextTags(String s, String tag) {
    s = s.replaceFirst(tag, "");
    if (tag.equals(SUB_START)) {
        s = s.replaceFirst(SUB_END, "");
    }else if (tag.equals(SUP_START)) {
        s = s.replaceFirst(SUP_END, "");
    }
    return s;
}
/**
 * 判斷是不是包含sub、sup標(biāo)簽
 * @param s
 * @return
 */
public static boolean containTag(String s) {
    return (s.contains(SUB_START) && s.contains(SUB_END)) || (s.contains(SUP_START) && s.contains(SUP_END));
}
/**
 * 處理字符串,得到每個(gè)sub、sup標(biāo)簽的開始和對(duì)應(yīng)的結(jié)束的標(biāo)簽的index
 * @param s
 * @param tagIndexList 傳一個(gè)新建的空list進(jìn)來,方法結(jié)束的時(shí)候會(huì)存儲(chǔ)好標(biāo)簽位置信息。
 * <br>tagIndexList.get(0)存放的sub
 * <br>tagIndexList.get(1)存放的是sup
 *
 * @return 返回sub、sup處理完之后的字符串
 */
public static String getIndexs(String s, List<List<int[]>> tagIndexList) {
    List<int[]> subs = Lists.newArrayList();
    List<int[]> sups =  Lists.newArrayList();
    while (true) {
        int[] sub_pair = getNextTagsIndex(s, SUB_START);
        if (Objects.nonNull(sub_pair)) {
            int firstStart = sub_pair[0];
            if (firstStart > -1) {
                int firstEnd = s.indexOf(SUB_END);
                String startString = s.substring(0, firstStart);
                String centreString = s.substring(firstStart, firstEnd);
                String endString = s.substring(firstEnd, s.length());
                if (centreString.contains(SUP_START)) {
                    centreString = centreString.replaceAll(SUP_START, "").replaceAll(SUP_END, "");
                    s = startString + centreString + endString;
                }
            }
        }
        int[] sup_pair = getNextTagsIndex(s, SUP_START);
        if (Objects.nonNull(sup_pair)) {
            int firstStart = sup_pair[0];
            if (firstStart > -1) {
                int firstEnd = s.indexOf(SUP_END);
                String startString = s.substring(0, firstStart);
                String centreString = s.substring(firstStart, firstEnd);
                String endString = s.substring(firstEnd, s.length());
                if (centreString.contains(SUB_START)) {
                    centreString = centreString.replaceAll(SUB_START, "").replaceAll(SUB_END, "");
                    s = startString + centreString + endString;
                }
            }
        }
        boolean subFirst = false;
        boolean supFirst = false;
        List a = new ArrayList();
        if (Objects.nonNull(sub_pair)) {
            a.add(sub_pair[0]);
        }
        if (Objects.nonNull(sup_pair)) {
            a.add(sup_pair[0]);
        }
        Collections.sort(a);
        if (Objects.nonNull(sub_pair)) {
            if (sub_pair[0] == Integer.parseInt(a.get(0).toString())) {
                subFirst = true;
            }
        }
        if (Objects.nonNull(sup_pair)) {
            if (sup_pair[0] == Integer.parseInt(a.get(0).toString())) {
                supFirst = true;
            }
        }
        if (sub_pair != null && subFirst) {
            s = removeNextTags(s, SUB_START);
            //<sub>標(biāo)簽被去掉之后,結(jié)束標(biāo)簽需要相應(yīng)往前移動(dòng)
            sub_pair[1] = sub_pair[1] - SUB_START.length();
            subs.add(sub_pair);
            continue;
        }
        if (sup_pair != null && supFirst) {
            s = removeNextTags(s, SUP_START);
            //<sup>標(biāo)簽被去掉之后,結(jié)束標(biāo)簽需要相應(yīng)往前移動(dòng)
            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;
}

然后我們通過獲取上下標(biāo)標(biāo)簽的下標(biāo),來完成字符的替換,至于要替換的Unicode是存在哪里,這個(gè)自己設(shè)計(jì)。
首先我們要把指定的字符轉(zhuǎn)成Unicode的:

unicode = StringEscapeUtils.unescapeJava(unicode);

然后通過全局的字符builder來重新構(gòu)造字符串:

StringBuilder sb  = new StringBuilder(value);
unicode = StringEscapeUtils.unescapeJava(unicode);
sb.replace(pair[0], pair[1], unicode);

到此這篇關(guān)于JAVA實(shí)現(xiàn)Excel和PDF上下標(biāo)的文章就介紹到這了,更多相關(guān)JAVA Excel和PDF上下標(biāo)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 三種SpringBoot中實(shí)現(xiàn)異步調(diào)用的方法總結(jié)

    三種SpringBoot中實(shí)現(xiàn)異步調(diào)用的方法總結(jié)

    Spring Boot 提供了多種方式來實(shí)現(xiàn)異步任務(wù),這篇文章主要為大家介紹了常用的三種實(shí)現(xiàn)方式,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2023-05-05
  • Java字符串編碼解碼性能提升的技巧分享

    Java字符串編碼解碼性能提升的技巧分享

    這篇文章主要是和大家分享幾個(gè)Java中提升字符串編碼解碼性能的小技巧,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定的幫助,需要的可以參考一下
    2022-05-05
  • Spring Boot jar 啟動(dòng)時(shí)設(shè)置環(huán)境參數(shù)的操作

    Spring Boot jar 啟動(dòng)時(shí)設(shè)置環(huán)境參數(shù)的操作

    這篇文章主要介紹了Spring Boot jar 啟動(dòng)時(shí)設(shè)置環(huán)境參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • springboot項(xiàng)目中application.properties無法變成小樹葉問題解決方案

    springboot項(xiàng)目中application.properties無法變成小樹葉問題解決方案

    這篇文章主要介紹了springboot項(xiàng)目中application.properties無法變成小樹葉問題解決,本文通過圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • Java中遇到的For?input?string問題解決辦法

    Java中遇到的For?input?string問題解決辦法

    這篇文章主要給大家介紹了關(guān)于Java中遇到的For?input?string問題的解決辦法,如果出現(xiàn)這樣的異常報(bào)錯(cuò),是指的數(shù)據(jù)轉(zhuǎn)換時(shí)出錯(cuò),文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • Spring Cloud學(xué)習(xí)教程之Zuul統(tǒng)一異常處理與回退

    Spring Cloud學(xué)習(xí)教程之Zuul統(tǒng)一異常處理與回退

    Spring Cloud Zuul對(duì)異常的處理整體來說還是比較方便的,流程也比較清晰,下面這篇文章主要給大家介紹了關(guān)于Spring Cloud學(xué)習(xí)教程之Zuul統(tǒng)一異常處理與回退的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04
  • Java中十進(jìn)制和十六進(jìn)制的相互轉(zhuǎn)換方法

    Java中十進(jìn)制和十六進(jìn)制的相互轉(zhuǎn)換方法

    下面小編就為大家?guī)硪黄狫ava中十進(jìn)制和十六進(jìn)制的相互轉(zhuǎn)換方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • Lombok注解-@SneakyThrows的使用

    Lombok注解-@SneakyThrows的使用

    這篇文章主要介紹了Lombok注解-@SneakyThrows的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java項(xiàng)目開發(fā)中實(shí)現(xiàn)分頁的三種方式總結(jié)

    Java項(xiàng)目開發(fā)中實(shí)現(xiàn)分頁的三種方式總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java項(xiàng)目開發(fā)中實(shí)現(xiàn)分頁的三種方式,通過這一篇文章可以很快的學(xué)會(huì)java分頁功能,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Java中不用第三個(gè)變量來互換兩個(gè)變量的值

    Java中不用第三個(gè)變量來互換兩個(gè)變量的值

    在程序運(yùn)行期間,隨時(shí)可能產(chǎn)生一些臨時(shí)數(shù)據(jù),應(yīng)用程序會(huì)將這些數(shù)據(jù)保存在一些內(nèi)存單元中,每個(gè)內(nèi)存單元都用一個(gè)標(biāo)識(shí)符來標(biāo)識(shí)。這些內(nèi)存單元被稱為變量,定義的標(biāo)識(shí)符就是變量名,內(nèi)存單元中存儲(chǔ)的數(shù)據(jù)就是變量的值
    2021-10-10

最新評(píng)論

牙克石市| 类乌齐县| 琼结县| 苍南县| 乐平市| 虎林市| 绥化市| 威信县| 湖北省| 晋州市| 万源市| 连江县| 新晃| 会理县| 建湖县| 海原县| 满洲里市| 象州县| 西城区| 建始县| 昂仁县| 北流市| 焦作市| 吉隆县| 门源| 桐乡市| 九江县| 琼结县| 汶川县| 大余县| 枣庄市| 房山区| 乌鲁木齐市| 太湖县| 富民县| 孟村| 武夷山市| 芦山县| 即墨市| 图们市| 濮阳县|