欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

1、簡介

最近項目需要實現(xiàn)26個小寫字母的上下標(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的樣例實現(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>

實現(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è)置第二個字符為上標(biāo) "c"
richTextString.applyFont(2, 3, font); // 設(shè)置第三個字符為下標(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、造字

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

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

在這里插入圖片描述

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

在這里插入圖片描述

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

在這里插入圖片描述

4、PDF

生成的PDF,采用開源的是開放源碼的站點sourceforge一個項目itextpdf,是用于生成PDF文檔的一個java類庫。通過iText不僅可以生成PDF或rtf的文檔,而且可以將XML、Html文件轉(zhuǎn)化為PDF文件。因項目通過Excel來轉(zhuǎn)PDF,但是因itextpdf無法識別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來實現(xiàn)實現(xiàn)加載:

String value = "設(shè)計強度?\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è)計可以通過造字來實現(xiàn)上下標(biāo)字母,現(xiàn)在我們可以通過指定字符來實現(xiàn)當(dāng)前上下標(biāo)的標(biāo)簽替換,設(shè)計上下標(biāo)通過標(biāo)簽來包裹,類似:下標(biāo):<sub> </sub> 上標(biāo):<sup><sup>來標(biāo)簽指定上下標(biāo)。
通過解析當(dāng)前字符串上下標(biāo)標(biāo)簽來實現(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>";
/**
 * 獲取下一對標(biāo)簽的index,不存在這些標(biāo)簽就返回null
 * @param s
 * @param tag SUB_START或者SUP_START
 * @return int[]中有兩個元素,第一個是開始標(biāo)簽的index,第二個元素是結(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;
}
/**移除下一對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));
}
/**
 * 處理字符串,得到每個sub、sup標(biāo)簽的開始和對應(yīng)的結(jié)束的標(biāo)簽的index
 * @param s
 * @param tagIndexList 傳一個新建的空list進來,方法結(jié)束的時候會存儲好標(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)往前移動
            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)往前移動
            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是存在哪里,這個自己設(shè)計。
首先我們要把指定的字符轉(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實現(xiàn)Excel和PDF上下標(biāo)的文章就介紹到這了,更多相關(guān)JAVA Excel和PDF上下標(biāo)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 泛談Java NIO

    泛談Java NIO

    java.nio全稱java non-blocking IO,是指jdk1.4 及以上版本里提供的新api(New IO),使用它可以提供非阻塞式的高伸縮性網(wǎng)絡(luò)。下面我們來簡單了解一下吧
    2019-05-05
  • 將Swagger2文檔導(dǎo)出為HTML或markdown等格式離線閱讀解析

    將Swagger2文檔導(dǎo)出為HTML或markdown等格式離線閱讀解析

    這篇文章主要介紹了將Swagger2文檔導(dǎo)出為HTML或markdown等格式離線閱讀,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • Java線程的全方位詳解

    Java線程的全方位詳解

    Java 給多線程編程提供了內(nèi)置的支持。 一條線程指的是進程中一個單一順序的控制流,一個進程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務(wù),多線程是多任務(wù)的一種特別的形式,但多線程使用了更小的資源開銷
    2021-10-10
  • Java中sharding-jdbc按年月分片的示例代碼

    Java中sharding-jdbc按年月分片的示例代碼

    本文主要介紹了Java中sharding-jdbc按年月分片的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Java跨模塊調(diào)用方式

    Java跨模塊調(diào)用方式

    這篇文章主要介紹了Java跨模塊調(diào)用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot實現(xiàn)掃碼登錄的示例代碼

    SpringBoot實現(xiàn)掃碼登錄的示例代碼

    本文主要介紹了SpringBoot實現(xiàn)掃碼登錄的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Springboot實現(xiàn)Activemq死信隊列詳解

    Springboot實現(xiàn)Activemq死信隊列詳解

    這篇文章主要介紹了Springboot實現(xiàn)Activemq死信隊列詳解,Activemq服務(wù)端配置重新投遞次數(shù)超過?MaximumRedeliveries?,則會進入死信隊列,默認(rèn)情況,有一個死信隊列:AcitveMQ.DLQ,所有的消息都投遞到此隊列,包括過期消息,重投遞失敗消息,需要的朋友可以參考下
    2023-12-12
  • @WebFilter在SpringBoot無效的原因分析和解決方案

    @WebFilter在SpringBoot無效的原因分析和解決方案

    使用Ruoyi的demo部署成功后,發(fā)現(xiàn)js、css等靜態(tài)文件都進入了過濾器,但是發(fā)現(xiàn)靜態(tài)文件沒有使用瀏覽器緩存,新建BrowserCacheFilter.java并增加@WebFilter處理,應(yīng)用自動重啟后發(fā)現(xiàn)@WebFilter無效,所以本文給大家介紹了@WebFilter在SpringBoot無效的原因分析和解決方案
    2024-03-03
  • Java每隔兩個數(shù)刪掉一個數(shù)問題詳解

    Java每隔兩個數(shù)刪掉一個數(shù)問題詳解

    這篇文章主要介紹了Java每隔兩個數(shù)刪掉一個數(shù)問題詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 基于java查找并打印輸出字符串中字符出現(xiàn)次數(shù)

    基于java查找并打印輸出字符串中字符出現(xiàn)次數(shù)

    這篇文章主要介紹了基于java查找并打印輸出字符串中字符出現(xiàn)次數(shù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11

最新評論