拆分word段落並保留H5樣式

1、功能需求

   1.1、需求明細

       1、將word文本轉換爲html
       2、提取三級標題下的H5內容(包括表格、圖片)
       3、將三級標題內容提取爲【一級類型】、【二級類型】

   1.2、原word文件樣式

     參考樣例文件:wordSample.docx    提取碼:u794
     

 

2、設計思路

2.1、利用github開源項目:java-mammoth 實現word2html功能

        java-mammoth 項目github鏈接:https://github.com/mwilliamson/java-mammoth

        pom配置信息:

           <dependency> 
               <groupId>org.zwobble.mammoth</groupId> 
               <artifactId>mammoth</artifactId> 
               <version>1.4.1</version> 
           </dependency>

2.2、生成的html文件中一級標題、二級標題、三級標題分別爲h1、h2、h3標籤;利用標籤的差異進行字符串處理獲取三級標題H5內容

 1、接收處理後的段落信息

              

	
public class HtmlRecord {

    private String type1;
    private String type2;
    private String key;
    private String content;

    public String getType1() {
        return type1;
    }

    public void setType1(String type1) {
        this.type1 = type1;
    }

    public String getType2() {
        return type2;
    }

    public void setType2(String type2) {
        this.type2 = type2;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

 2、html拆分處理邏輯


    public static void main(String[] args) {
        try{
            DocumentConverter converter = new DocumentConverter();
            Result<String> result = converter.convertToHtml(new File("D:\\abc.docx"));
            String html = result.getValue(); // The generated HTML
            getHeadItems(html);
            Set<String> warnings = result.getWarnings();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     *  獲取三級標題內容列表
     * @param html  word轉換生成的html內容
     * @return
     */
    private static List<HtmlRecord> getHeadItems(String html){
        List<HtmlRecord> records = new ArrayList<>();

        // 當前一級標題名稱
        String h1Name = "";
        // 當前二級標題名稱
        String h2Name = "";
        // 當前三級標題名稱
        String h3Name = "";
        // 當前三級標題對應內容
        String h3Content = "";
        // 上一級標題結束下標
        int lastEndIndex = 0;
        // 上次標籤爲三級標題
        boolean isH3Tag = false;
        //String html3 = "<h1>dafa</h1><h2>123456</h2><h2>ddddd</h2><h3>aaaa</h3><a id=\"_Toc518917206\"></a>三、合規管理 <h1><p><strong>雲南國際信託有限公司</strong></p></h1><h3>33333</h3><a id=\"_Toc518917206\"></a>三、合規管理";
        // 標題標籤正則匹配式
        Pattern pattern = Pattern.compile("<h[1-3]{1}>(.*?)</[h][1-3]{1}>");
        Matcher matcher = pattern.matcher(html);
        // 匹配任意三級標題前部分
        while(matcher.find()){
            //boolean result2 = matcher2.find();
            // 三級標題前部分開始下標
            int startIndex = matcher.start();
            // 三級標題後部分開始下標
            int endIndex = matcher.end();
            // 獲取標題標籤之間內容
            String tagContent = html.substring(startIndex + 4,endIndex-5);
            // 獲取標題標籤名稱
            String tag =  matcher.group().substring(0,4);


            // 上一次爲三級標題標籤
            if(isH3Tag){
                // 上次標籤後部分結束下標 - 本次標籤前部分開始下標 之間的內容
                h3Content = html.substring(lastEndIndex, startIndex);
                HtmlRecord htmlRecord = new HtmlRecord();
                htmlRecord.setType1(getOnlyHeadContent(h1Name));
                htmlRecord.setType2(getOnlyHeadContent(h2Name));
                htmlRecord.setKey(getOnlyHeadContent(h3Name));
                String dateStr = getDateStrFromHeadStr(h3Name);
                htmlRecord.setPublishDt(dateStr);
                htmlRecord.setContent(h3Content);
                htmlRecord.setPublishDept("合規部門");
                records.add(htmlRecord);
            }

            isH3Tag = false;
            if(Objects.equals(tag, "<h1>")){
                // 當前爲一級標題,重置一級標題名和二級標題名
                h1Name = tagContent;
                h2Name = "";
            }else if(Objects.equals(tag, "<h2>")){
                // 當前爲二級標題,重置二級標題名
                h2Name =tagContent;
            }else{
                // 當前爲三級標題,重置二級標題名
                h3Name = tagContent;
                isH3Tag = true;
                // 獲取三級標題後部分結束下標
                lastEndIndex = endIndex;
            }
        }
        // 處理最後一個三級標題內容
        String tagContent = html.substring(lastEndIndex);
        HtmlRecord htmlRecord = new HtmlRecord();
        htmlRecord.setType1(getOnlyHeadContent(h1Name));
        htmlRecord.setType2(getOnlyHeadContent(h2Name));
        htmlRecord.setKey(getOnlyHeadContent(h3Name));
        String dateStr = getDateStrFromHeadStr(h3Name);
        htmlRecord.setPublishDt(dateStr);
        htmlRecord.setContent(tagContent);
        records.add(htmlRecord);
        htmlRecord.setPublishDept("合規部門");
        return records;
    }

    /**
     * 獲取標題文本內容
     * @param headHtml  標題h5內容
     * @return
     */
    private static String getOnlyHeadContent(String headHtml){
        if(StringUtils.isBlank(headHtml)){
            return "";
        }

        String headContentStr = "";
        Pattern pattern = Pattern.compile("<a[^>]*>([^<]*)</a>");
        Matcher matcher = pattern.matcher(headHtml);
        while(matcher.find()){
            String content = matcher.group();
            System.out.println(content);
            headHtml = headHtml.replace(content,"");
        }
        headContentStr = headHtml;
        return headContentStr;
    }

    /**
     *  從標題中抽取時間信息
     * @param headStr 標題內容
     * @return
     */
    private static String getDateStrFromHeadStr(String headStr){
        if(StringUtils.isBlank(headStr)){
            return "";
        }
        String dateStr = "";
        Pattern dtPattern = Pattern.compile("20[0-9]{2}年[1-9]{1,2}月[1-9]{1,2}日");
        Matcher dtMatcher = dtPattern.matcher(headStr);
        if(dtMatcher.find()){
            dateStr = dtMatcher.group();
            dateStr = dateStr.replace("年","-");
            dateStr = dateStr.replace("月","-");
            dateStr = dateStr.replace("日","");
            System.out.println(dateStr);
        }
        return dateStr;
    }

3、設計不足之處

3.1、 java-mammoth 轉換生成html 中表格沒有邊豎線,這點在項目也有說明

      

解決方式:不使用pom方式引入jar包; 手動下載項目整合到所需項目中

  調整internal/conversion/DocumentToHtml中visit(Table table, Context context)代碼,添加border樣式即可實現表格的邊框效果

 

3.2、java-mammoth會將圖片直接base64文本,如果word中存在大量圖片,直接將轉換後的html存入數據庫,會造成數據庫存儲、查詢負擔; 可以在處理過程中base64圖片還原存儲至文件服務器

3.3、待處理word的樣式存在要求限制,若不滿足則無法正常處理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章