Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 日韩专区中文字幕,精品国产一区二区三区四区色,亚洲小说欧美激情另类

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          SpringBoot項目使用EasyPoi實現導入導

          SpringBoot項目使用EasyPoi實現導入導出,就是這么的絲滑

          Hi,大家好,我是希留。

          在項目的開發工程中,經常有導入導出數據的常見功能場景,Apache的POI是處理導入導出中最常用的,但是其原生的用法太復雜,很繁瑣,總是在Copy… ,無意間發現一款簡單粗暴的神器EasyPoi,EasyPoi也是基于POI的,在SpringBoot中也是做了很好的封裝,讓我們能夠在SpringBoot 快速地使用 EasyPoi 進行開發,很方便,而且支持多種格式的導入導出。


          本篇文章就給大家介紹下EasyPoi。如果對你有幫助的話,還不忘點贊支持一下,感謝!文末附有源碼


          目錄

          • 一、EasyPoi簡介
          • 二、EasyPoi主要功能
          • 三、EasyPoi注解介紹
          • 四、開始使用

          一、EasyPoi簡介

          EasyPoi功能如同名字easy,主打的功能就是容易,讓一個沒見接觸過poi的人員就可以方便的寫出Excel導出,Excel模板導出,Excel導入,Word模板導出,通過簡單的注解和模板語言(熟悉的表達式語法),完成以前復雜的寫法。


          最新官方文檔:

          http://doc.wupaas.com/docs/easypoi/easypoi-1c0u6ksp2r091


          二、EasyPoi主要功能

          • 基于注解的導入導出,修改注解就可以修改Excel
          • 支持常用的樣式自定義
          • 基于map可以靈活定義的表頭字段
          • 支持一對多的導出,導入
          • 支持模板的導出,一些常見的標簽,自定義標簽
          • 支持HTML/Excel轉換,如果模板還不能滿足用戶的變態需求,請用這個功能
          • 支持word的導出,支持圖片,Excel

          三、EasyPoi注解介紹

          easypoi起因就是Excel的導入導出,最初的模板是實體和Excel的對應,model–row,filed–col 這樣利用注解我們可以和容易做到excel到導入導出。


          1、@Excel

          這個是必須使用的注解,如果需求簡單只使用這一個注解也是可以的,涵蓋了常用的Excel需求。

          屬性

          類型

          默認值

          功能

          name

          String

          null

          列名

          orderNum

          String

          “0”

          列的排序

          replace

          String[]

          {}

          值的替換 {a_id,b_id}

          type

          int

          1

          導出類型 1 是文本 2 是圖片,3 是函數,
          10是數字
          默認是文本

          exportFormat

          String

          “”

          導出的時間格式,以這個是否為空來判斷
          是否需要格式化日期

          importFormat

          String

          “”

          導入的時間格式,以這個是否為空來判斷是否需要格式化日期

          format

          String

          “”

          時間格式,相當于同時設置了exportForm
          at和 importFormat

          suffix

          String

          “”

          文字后綴,如% 90 變成90%

          isHyperlink

          boolean

          false

          超鏈接,如果是需要實現接口返回對象

          isImportField

          boolean

          true

          校驗字段,看看這個字段是不是導入
          的Excel中有,如果沒有說明是錯誤的
          Excel,讀取失敗,支持name_id

          2、@ExcelCollection

          一對多的集合注解,用以標記集合是否被數據以及集合的整體排序

          屬性

          類型

          默認值

          功能

          id

          String

          null

          定義ID

          name

          String

          null

          定義集合列名,
          支持nanm_id

          orderNum

          int

          0

          排序,支持name_id

          type

          Class<?>

          ArrayList.class

          導入時創建對象使用

          四、開始使用

          1、添加依賴

          Maven 依賴:

          <dependency>
             <groupId>cn.afterturn</groupId>
             <artifactId>easypoi-spring-boot-starter</artifactId>
             <version>4.2.0</version>
          </dependency>

          2、導入功能實現

          首先定義需要導入的數據類型UserImportVO,并使用@Excel注解與excel列映射,導入的時候通常需要對導入的數據進行一些校驗

          2.1 UserImportVO導入類

          EasyPoi的校驗使用也很簡單,對象上加上通用的校驗規則,配置下需要校驗就可以了,校驗主要是JSR 303 規范,可結合Hibernate Validator使用

          導入類對象實現IExcelModel、IExcelDataModel 接口,可獲取到錯誤校驗信息。

          @Data
          public class UserImportVO implements Serializable,IExcelModel, IExcelDataModel {
          
              @NotBlank
              @Excel(name="姓名")
              private String realName;
          
              @Excel(name="性別", replace={ "男_1", "女_2" })
              private Integer sex;
          
              @Excel(name="出生日期", format="yyyy-MM-dd")
              private Date birthday;
          
              @Length(min=1, max=11, message="請填寫正確的手機號")
              @Excel(name="手機號碼")
              private String phone;
          
              @Excel(name="固定電話")
              private String tel;
          
              @Email(message="請填寫正確的郵箱地址")
              @Excel(name="郵箱")
              private String email;
          
              @Excel(name="頭像地址")
              private String avatar;
          
              @Excel(name="信息")
              private String errorMsg;
          
              private Integer rowNum;
          
              @Override
              public Integer getRowNum() {
                  return this.rowNum;
              }
          
              @Override
              public void setRowNum(Integer i) {
                  this.rowNum=i;
              }
          
              @Override
              public String getErrorMsg() {
                  return this.errorMsg;
              }
          
              @Override
              public void setErrorMsg(String s) {
                  this.errorMsg=s;
              }
          }

          在編寫controller層導入方法

          @Autowired
          private IUserService userService;
          
            @PostMapping("/importExcel")
            public String importExcel(@RequestParam("file") MultipartFile file) {
                  try {
                      String result=userService.importExcel(file);
                      return result;
                  } catch (Exception e) {
                      return "導入失敗";
                  }
             }

          2.3 service層

          具體的實現是在service層

          
             @Autowired
              private UserVerifyHandler userVerifyHandler;
          
              @Override
              public String importExcel(MultipartFile file) throws Exception{
                  ImportParams importParams=new ImportParams();
                  //表格標題行數,默認0
                  importParams.setTitleRows(1);
                  //是否需要校驗上傳的Excel
                  importParams.setNeedVerify(true);
                  //告訴easypoi我們自定義的驗證器
                  importParams.setVerifyHandler(userVerifyHandler);
                  ExcelImportResult<UserImportVO> result=ExcelImportUtil.importExcelMore(file.getInputStream(),UserImportVO.class,importParams);
                  if (!result.isVerifyFail() && !CollectionUtils.isEmpty(result.getList())) {
                      for (UserImportVO vo : result.getList()) {
                          log.info("從Excel導入數據到數據庫的詳細為 :{}", vo);
                          User user=new User();
                          BeanUtil.copyProperties(vo,user);
                          this.save(user);
                      }
                  } else {
                      for (UserImportVO vo : result.getFailList()) {
                          log.info("校驗失敗的詳細為 :{}", vo);
                      }
                      return "文檔校驗失敗";
                  }
                  return "導入成功";
              }
          

          2.4 ImportParams 參數

          導入參數介紹下

          屬性

          類型

          默認值

          功能

          titleRows

          int

          0

          表格標題行數,默認0

          headRows

          int

          1

          表頭行數,默認1

          startRows

          int

          0

          字段真正值和列標題之間
          的距離 默認0

          startSheetIndex

          int

          0

          開始讀取的sheet位置,
          默認為0

          needVerfiy

          boolean

          false

          是否需要校驗上傳的Excel

          needSave

          boolean

          false

          是否需要保存上傳的Excel

          saveUrl

          String

          “upload
          /excelUpload”

          保存上傳的Excel目錄,默認
          是 如 TestEntity這個類保存路徑就是upload/excelUpload/Test/yyyyMMddHHmss* 保存名稱上傳時間五位隨機數

          importFields

          String[]

          null

          導入時校驗數據模板,是不是正確的Excel

          verifyHanlder

          IExcelVerifyHandler

          null

          校驗處理接口,自定義校驗

          dataHanlder

          IExcelDataHandler

          null

          數據處理接口,以此為主,replace,format都在這后面


          2.5 自定義校驗規則

          通用的校驗滿足不了所有的校驗,例如還需要通過查詢數據庫,校驗數據的唯一性,此時需要自定義一個校驗規則,實現IExcelVerifyHandler接口。

          @Component
          public class UserVerifyHandler implements IExcelVerifyHandler<UserImportVO> {
          
              @Autowired
              private IUserService userService;
          
              @Override
              public ExcelVerifyHandlerResult verifyHandler(UserImportVO vo) {
                  ExcelVerifyHandlerResult result=new ExcelVerifyHandlerResult();
                  //假設我們要添加用戶,現在去數據庫查詢realName,如果存在則表示校驗不通過。
                  User user=userService.getOne(new LambdaQueryWrapper<User>().eq(User::getRealName,vo.getRealName()));
                  if (user!=null) {
                      result.setMsg("唯一校驗失敗");
                      result.setSuccess(false);
                      return result;
                  }
                  result.setSuccess(true);
                  return result;
              }
          }

          2.6 測試

          1.此時,基本上的代碼就編寫完了,開始測試:

          使用postman工具進行導入測試,先填充一些不符合規則的數據,可以看到控制臺輸出的校驗錯誤的信息。

          圖1-1 測試導入的execl

          圖1-2 postman工具請求接口返回

          圖1-3 控制臺輸出

          2.再填充一些符合規則的數據,可以看到導入成功,數據庫成功插入數據。

          圖2-1 測試導入的execl

          圖2-2 postman工具請求接口返回

          圖2-3 數據庫數據

          3、導出功能實現

          3.1 UserExportVO導出類

          導出類不需要配置校驗規則,只需定義要導出的信息

          @Data
          public class UserExportVO implements Serializable {
          
              @Excel(name="姓名")
              private String realName;
          
              @Excel(name="性別", replace={ "男_1", "女_2" }, suffix="生")
              private Integer sex;
          
              @Excel(name="出生日期", format="yyyy-MM-dd")
              private Date birthday;
          
              @Excel(name="手機號碼")
              private String phone;
          
              @Excel(name="固定電話")
              private String tel;
          
              @Excel(name="郵箱")
              private String email;
          
              @Excel(name="頭像地址")
              private String avatar;
          
          }

          3.2 controller層

          編寫controller層導出方法

           @GetMapping("/exportExcel")
           public void export(HttpServletResponse response) {
                  //查詢要導出的數據
                  List<UserExportVO> users=userService.getUserExportList();
                  ExcelUtil.exportExcelX(users, "測試導出表", "sheet1", UserExportVO.class, "測試導出表.xlsx", response);
           }
          

          3.3 service層

          編寫service層查詢需要導出的數據,把查詢出來的集合轉化成導出VO集合。

          @Override
          public List<UserExportVO> getUserExportList() {
                  List<User> users=this.list();
                  //users集合轉成export集合
                  List<UserExportVO> exportVOList=users.stream().map(user -> {
                      UserExportVO vo=new UserExportVO();
                      BeanUtils.copyProperties(user, vo);
                      return vo;
                  }).collect(Collectors.toList());
                  return exportVOList;
          }

          3.4 測試

          直接瀏覽器請求導出接口,成功導出。

          圖3-1 請求導出接口

          圖3-2 導出結果


          結語

          好了,以上就是今天要講的內容,本文僅僅簡單介紹了使用EasyPoi導入導出功能的使用,而EasyPoi還提供了模板的導出、圖片的導出、word的導出等等功能,感興趣的朋友,可查閱官方文檔進一步探究。

          本次demo源碼:
          Gitee地址:https://gitee.com/huoqstudy/java-sjzl-demo/tree/master/springboot-easypoi-demo

          Github地址:https://github.com/277769738/java-sjzl-demo/tree/master/springboot-easypoi-demo

          產品期望實現【公文管理】其中發文擬文一塊內容,用戶上傳正文(word),再選擇不同套紅模板,最后拼接為一個對外發文,的公文格式。

          基于上次使用vue實現在線編輯功能,產品不太滿意,重新學習java如何操作word文檔,之前地址:(vue使用Tinymce富文本模擬在線word文檔)juejin.cn/post/723665…

          最終效果

          有兩個文件test1.docx (作為紅頭模板)和test2.docx(作為正文);期望實現效果:用戶選擇紅頭模板加上自己寫的正文內容,最終生成可編輯的word文檔。

          create_table.docx 合并之后最終效果“

          test1.docx 紅頭模板:

          test2.docx 正文(用戶撰寫上傳的內容):

          準備階段

          技術選型

          1. docx4j:一個用 文檔的 Java 庫,具有良好的文檔合并功能。
          2. JODConverter:一個不依賴于 OpenOffice/LibreOffice 的 Java 庫,可以幫助開發者將 Office 文檔轉換成 PDF、HTML、XHTML、ODF 等格式,并支持合并 Word 文檔。
          3. Aspose.Words for Java:一個商業級的文檔處理庫,支持多種文檔格式的處理,包括 Word、PDF、HTML 等,并且支持合并 Word 文檔。
          4. FreeMarker:一個模板引擎庫,可以用于制作 Word 文檔模板,然后使用 Java 代碼生成文檔。
          5. Apache POI: 是一個開源的 Java 庫,可以用來讀寫 Microsoft Office 文檔,包括 Word、Excel、PowerPoint 等各種格式。它是 Apache 軟件基金會的一部分,最新版本是 5.0.0。

          如標題所示,最終采用Apache POI來實現這個功能主要原因:

          1. 讀取和創建 Microsoft Office 文檔,包括 Word、Excel、PowerPoint 等多種格式。
          2. 支持訪問和修改文檔的所有元素,比如文本、樣式、圖表、格式等。
          3. 提供豐富的工具類和方法,可以方便地進行文檔操作,比如把文本轉換成 HTML、從 Excel 中讀取數據、合并 Word 文檔等。
          4. 支持不同版本的 Office 文檔格式,包括舊版本和新版本。
          5. 支持批量處理大量文檔,提高了文檔處理的效率。

          主要是對于我這種初學者來說是非常友好的,太復雜玩不轉。Apache POI 的使用非常簡單,只需添加它的 jar 包到項目中,并調用相應的 API 即可實現文檔讀寫。同時,Apache POI 提供了豐富的文檔和官方網站上的文檔也很詳細。

          功能設計思路

          1. 創建一個空的 Word 文檔作為合并后的文檔。
          2. 讀取要合并的 Word 文檔(test1.doxc、test2.docx),并將它們的內容復制到合并后的文檔中。可以使用 Apache POI 中的 XWPFDocument 類來讀寫 Word 文檔。
          3. 保存合并后的文檔。使用 XWPFDocument 類的 write(OutputStream out) 方法將文檔保存到本地文件或輸出流中。

          功能實現

          Apache POI,分別為 Word、Excel、PowerPoint 等各種格式提供不同的類方法,我們需要操作Word文檔的功能,所以使用(Java API for Microsoft Documents)中的XWPFDocument類,實現文檔合并功能。

          整理不同格式文檔操作類

          1. HSSF: MS-Excel 97-2003(.xls),基于BIFF8格式的JAVA接口。
          2. XSSF:MS-Excel 2007+(.xlsx),基于OOXML格式的JAVA接口。
          3. HWPF: MS-Word 97-2003(.doc),基于BIFF8格式的JAVA接口。只支持.doc文件簡單的操作,讀寫能力有限。本API為POI項目早期開發,很不幸的 是主要負責HWPF模塊開發的工程師-"Ryan Ackley"已經離開Apache組織,現在該模塊沒有人維護、更新、完善。
          4. XWPF:MS-Word 2007+(.docx),基于OOXML格式的JAVA接口。較HWPF功能完善。

          注意:word文檔目前有兩種不同格式,一種是以doc結尾的,另一種以docx結尾,本次功能主要講解docx格式文檔操作,doc格式文檔調用的類和函數HWPF開頭。

          兩者區別:doc是Word2007及以下版的文件擴展名,而docx是Word2007及以上版本的文件擴展名,docx版本兼容性較高,而且比doc文件所占用空間更小。

          引入依賴

          在pom.xml文件中引入maven依賴,

                  <!-- WordToHtml .doc .odcx  poi  -->
                  <dependency>
                      <groupId>org.apache.poi</groupId>
                      <artifactId>poi-scratchpad</artifactId>
                      <version>4.1.2</version>
                  </dependency>
          
                  <!-- 操作excel的庫 注意版本保持一致 poi poi-ooxml  poi-scratchpad -->
                  <dependency>
                      <groupId>org.apache.poi</groupId>
                      <artifactId>poi</artifactId>
                      <version>4.1.2</version>
                  </dependency>
                  
                  <!--poi-ooxml和*poi-ooxml-schemas*是poi對2007及以上版本的擴充。-->
                  <dependency>
                      <groupId>org.apache.poi</groupId>
                      <artifactId>poi-ooxml-schemas</artifactId>
                      <version>4.1.2</version>
                  </dependency>
                  <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
                  <dependency>
                      <groupId>org.apache.poi</groupId>
                      <artifactId>poi-ooxml</artifactId>
                      <version>4.1.2</version>
                  </dependency>
          


          示例代碼

          簡化整體流程,創建兩個word文件test1.docx和test2.docx。將下列file對應的文件路徑換成自己創建的文件路徑創,建單個java文件(帶main),直接運行main方法輸出creat_table.docx文件。 先上代碼,再進行講解:

          package org.ssssssss.magicboot;
          
          import org.apache.poi.xwpf.usermodel.*;
          
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.util.List;
          
          public class WordDocumentTest {
              public static void main(String[] args) throws Exception
              {
                  //獲取文件轉io流
                  File file1=new File("D:/IDM/test1.docx");
                  File file2=new File("D:/IDM/test2.docx");
                  FileInputStream fis1=new FileInputStream(file1);
                  FileInputStream fis2=new FileInputStream(file2);
                  //最終文件輸出的路徑
                  FileOutputStream out=new FileOutputStream(new File("D:/IDM/create_table.docx"));
          
                  //轉為word文檔元素
                  XWPFDocument dcx1=new XWPFDocument(fis1);
                  XWPFDocument dcx2=new XWPFDocument(fis2);
          
                  //創建一個新的文檔
                  XWPFDocument document=new XWPFDocument();
          
          
                  //將第一個文檔元素復制新創建的文檔中;
                  document=dcx1;
          
                  //換行 document.createParagraph().createRun().addBreak();
          
                  //將第二個docx內容添加到新創建的文檔中
                  mergeParagraphs(dcx2.getParagraphs(), document);
                  //結束關閉io流
                  document.write(out);
                  out.close();
                  fis1.close();
                  fis2.close();
                  System.out.println("create_table document written success.");
          
              }
              // 合并文本段落
              private static void mergeParagraphs(List<XWPFParagraph> paragraphs, XWPFDocument outDoc) {
                  for (XWPFParagraph para : paragraphs) {
          
                      XWPFParagraph newPara=outDoc.createParagraph();
                      newPara.getCTP().setPPr(para.getCTP().getPPr());
                      //判斷是否是文本、段落、圖片 //.getRPr() para.tables !=null ,iruns 獲取圖片
          
                      for (XWPFRun run : para.getRuns()) {
                          XWPFRun newRun=newPara.createRun();
                          newRun.getCTR().setRPr(run.getCTR().getRPr());
                          newRun.setText(run.getText(0));
                      }
                  }
              }
          


          代碼解釋

          實現流程主要看代碼中的注釋,包含以下幾個步驟

          1. 獲取文件轉io流
          2. 將io流轉為word文檔元素(XWPFDocument)
          3. 創建一個新的文檔
          4. 將第一個文檔元素復制新創建的文檔中
          5. 將第二個docx內容添加到新創建的文檔中
          6. 輸出新文檔,關閉io流

          核心重點將第二個docx內容添加到新創建的文檔中封裝mergeParagraphs方法,在這個方法中傳入了兩個參數(List paragraphs, XWPFDocument outDoc) 其中List<XWPFParagraph> paragraphs=dcx2.getParagraphs() 意思是將dcx2文檔所有段落取出來用一個數組存放,再進行循環段落;通過XWPFParagraph newPara=outDoc.createParagraph();給新的文檔創建一個新的段落;給新的段落添加對應的樣式newPara.getCTP().setPPr(para.getCTP().getPPr());最后由于段落中會劃分不同的XWPFRun再進行循環設置文本的字體、大小、顏色、加粗、斜體、下劃線等格式。 官方api介紹

          剛才對XWPFRun沒有進行很好的解釋,這里重新舉例說明下,例如以下標紅的段落

          按照正常理解這一個段落內容應該是一個東西,其實在XWPF中會劃分為不同的XWPFRun,使用idea打斷點查看數據

          可以看出它將一段文字劃分為不同模塊,為什么會這樣,在一段文字中也存在不同的區別,例如文字的字體,像下圖中“根據”“2023”屬于不同的字體,所以會劃分為不同的XWPFRun,理解這個概念后同理明白為什么一個段落會劃分為29模塊

          相關函數

          在前面其實已經實現第一個模塊最終效果的docx文檔合并的功能,所以在這個模塊講解在實現這個過程中記錄有意思的內容。

          XWPFRun(文本段落)

          接著上面講XWPFRun這個函數,XWPFRun用于在 Word 文檔中添加或修改單個本 Run 或 Run 中的文字格式。它是文本段落(XWPFParagraph)中的最小單元,用于精細控制文本的格式和樣式。可以使用 XWPFRun 類的各種方法來設置文本的字體、大小、顏色、加粗、斜體、下劃線等格式。 下列是在使用過程中記錄的一些屬性,以及這些屬性對應能夠設置的格式注釋。

              XWPFRun run=firstParagraph.createRun();
                          XWPFRun tempRun=xwpfRuns.get(i);
              
                          //默認:宋體(wps)/等線(office2016) 5號 兩端對齊 單倍間距
                          run.setText(tempRun.text());
                          //加粗
                          run.setBold(tempRun.isBold());
                          //我也不知道這個屬性做啥的
                          run.setCapitalized(tempRun.isCapitalized());
                          //設置顏色--十六進制
                          run.setColor(tempRun.getColor());
                          //這個屬性報錯
                          run.setCharacterSpacing(tempRun.getCharacterSpacing());
                          //浮雕字體----效果和印記(懸浮陰影)類似
                          run.setEmbossed(tempRun.isEmbossed());
                          //雙刪除線
                          run.setDoubleStrikethrough(tempRun.isDoubleStrikeThrough());
                          run.setEmphasisMark(tempRun.getEmphasisMark().toString());
                          //字體,//字體,范圍----效果不詳
                          run.setFontFamily(tempRun.getFontFamily());
                          //字體大小,沒有設置默認是-1,
                          if(tempRun.getFontSize() !=-1){
                              run.setFontSize(tempRun.getFontSize());
                          }
                          //印跡(懸浮陰影)---效果和浮雕類似
                          run.setImprinted(tempRun.isImprinted());
                          //斜體(字體傾斜)
                          run.setItalic(tempRun.isItalic());
                          //字距調整----這個好像沒有效果
                          run.setKerning(tempRun.getKerning());
                          //陰影---稍微有點效果(陰影不明顯)
                          run.setShadow(tempRun.isShadowed());
                          //小型股------效果不清楚
                          run.setSmallCaps(tempRun.isSmallCaps());
                          //單刪除線(廢棄)
                          run.setStrike(tempRun.isStrike());
                          //單刪除線(新的替換Strike)
                          run.setStrikeThrough(tempRun.isStrikeThrough());
                          //下標(吧當前這個run變成下標)---枚舉
                          run.setSubscript(tempRun.getSubscript());
                          //設置兩行之間的行間距
                          run.setTextPosition(tempRun.getTextPosition());
                          //各種類型的下劃線(枚舉)
                          run.setUnderline(tempRun.getUnderline());
          
                          run.setVerticalAlignment(tempRun.getVerticalAlignment().toString());
                          run.setVanish(tempRun.isVanish());
                          run.setUnderlineThemeColor(tempRun.getUnderlineColor());
                          run.setUnderlineColor(tempRun.getUnderlineColor());
                          run.setTextScale(tempRun.getTextScale());
                          run.setTextPosition(tempRun.getTextPosition());
                          run.setTextHighlightColor(tempRun.getTextHightlightColor().toString());
          //                run.setStyle(tempRun.gets); 沒找到這個屬性
                          run.setLang(tempRun.getLang());
          


          XWPFParagraph(段落)

          XWPFParagraph 是 Apache POI 庫中 XWPF 模塊的一部分,用于創建或修改 Word 文檔中的段落。它可以添加不同的文本格式,并且可以添加圖片、表格、超鏈接等內容。XWPFParagraph 類可以控制段落的樣式和格式,包括字體、字號、行距、首行縮進、對齊方式等。可以使用 XWPFParagraph 類的各種方法來設置段落的格式和樣式。

              常用方法:
              //創建一個新的 XWPFRun 對象,用于在段落中添加文本或修改文本格式。
              createRun()
              //設置段落的對齊方式,align 參數可以是 LEFT、CENTER、RIGHT、JUSTIFY 等值。
              setAlignment(ParagraphAlignment align)
              //設置段落的行距和行距規則,lineSpacing 參數是行距大小(以磅為單位),lineSpacingRule 參數可以是 EXACT、AT_LEAST、AUTO 等值。
              setSpacingBetween(int lineSpacing, LineSpacingRule lineSpacingRule)
              //設置段落的左縮進大小(以磅為單位)。
              setIndentationLeft(int indentation)
              //設置段落的右縮進大小(以磅為單位)。
              setIndentationRight(int indentation)
              //設置段落的編號 ID。
              setNumID(BigInteger numId)
              //設置段落的編號格式,numFmt 參數可以是 DECIMAL、LOWERCASE_LETTER、UPPERCASE_LETTER 等值。
              setNumFmt(NumberFormat numFmt)
              //在段落中添加圖片,pictureType 參數是圖片類型,filename 參數是圖片文件名,width 和 height 參數是圖片寬度和高度。
              createPicture(XWPFRun run, int pictureType, String filename, int width, int height)
              
              其他方法:
              //指定應顯示在左邊頁面指定段周圍的邊界。
              setBorderBottom(Borders.APPLES); 
              //指定應顯示在下邊頁面指定段周圍的邊界。
              setBorderLeft(Borders.APPLES);
              //指定應顯示在右側的頁面指定段周圍的邊界。
              setBorderRight(Borders.ARCHED_SCALLOPS);
              //指定應顯示上方一組有相同的一組段邊界設置的段落的邊界。這幾個是對段落之間的格式的統一,相當于格式刷
              setBorderTop(Borders.ARCHED_SCALLOPS);
              //---正文寬度會稍微變窄 
              p1.setFirstLineIndent(99);
              //---段落的對齊方式 1左 2中 3右 4往上 左 不可寫0和負數
              p1.setFontAlignment(1);
              //---首行縮進,指定額外的縮進,應適用于父段的第一行。
              p1.setIndentationFirstLine(400);
              //---首行前進,指定的縮進量,應通過第一行回到開始的文本流的方向上移動縮進從父段的第一行中刪除。
              p1.setIndentationHanging(400);
              //---整段右移
              p1.setIndentFromLeft(400);
              //--此方法提供了樣式的段落,這非常有用。
              p1.setStyle("");
              //--此元素指定是否消費者應中斷超過一行的文本范圍,通過打破這個詞 (打破人物等級) 的兩行或通過移動到下一行 (在詞匯層面上打破) 這個詞的拉丁文字。
              p1.setWordWrapped(true);
              //---指定的文本的垂直對齊方式將應用于此段落中的文本 
              p1.setVerticalAlignment(TextAlignment.CENTER);
              //--指定行之間的間距如何計算存儲在行屬性中。 
              p1.setSpacingLineRule(LineSpacingRule.AT_LEAST);
              //--指定應添加在此線單位在文檔中的段落的第一行之前的間距。
              p1.setSpacingBeforeLines(6);  
              //--指定應添加上面這一段文檔中絕對單位中的第一行的間距。
              p1.setSpacingBefore(6); 
              //--指定應添加在此線單位在文檔中的段落的最后一行之后的間距。 
              p1.setSpacingAfterLines(6);
              //--指定應添加在文檔中絕對單位這一段的最后一行之后的間距。
              p1.setSpacingAfter(6); 
              //--指定當渲染此分頁視圖中的文檔,這一段的內容都呈現在文檔中的新頁的開始。
              p1.setPageBreak(true);
          


          其他功能

          剛在展示活動內容都是根據自身的需求寫小demo,實際項目遠遠不止這些內容,其中還是存在不足之處,例如word中的表格、圖片都是需要單獨處理,表格有個專門類XWPFTable;圖片也有XWPFPictureData、 XWPFPicture

          學習參考

          Apache POI 官方網站提供了完整的 API 文檔:poi.apache.org/apidocs/dev…

          Apache POI 的 GitHub 倉庫中查看示例代碼和文檔:github.com/apache/poi

          Java POI 生成Word文檔:blog.csdn.net/qq_34755766…

          Apache POI 中文版download.csdn.net/download/qq…


          作者:沐游虞
          轉自:https://juejin.cn/post/7237487091554730021
          來源:稀土掘金
          著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

          、前言

          實現文檔在線預覽的方式除了上篇文章 文檔在線預覽新版(一)通過將文件轉成圖片實現在線預覽功能說的將文檔轉成圖片的實現方式外,還有轉成pdf,前端通過pdf.js、pdfobject.js等插件來實現在線預覽,以及本文將要說到的將文檔轉成html的方式來實現在線預覽。

          以下代碼分別提供基于aspose、pdfbox、spire來實現來實現txt、word、pdf、ppt、word等文件轉圖片的需求。

          1、aspose

          Aspose 是一家致力于.Net ,Java,SharePoint,JasperReports和SSRS組件的提供商,數十個國家的數千機構都有用過aspose組件,創建、編輯、轉換或渲染 Office、OpenOffice、PDF、圖像、ZIP、CAD、XPS、EPS、PSD 和更多文件格式。注意aspose是商用組件,未經授權導出文件里面都是是水印(尊重版權,遠離破解版)。

          需要在項目的pom文件里添加如下依賴

                  <dependency>
                      <groupId>com.aspose</groupId>
                      <artifactId>aspose-words</artifactId>
                      <version>23.1</version>
                  </dependency>
                  <dependency>
                      <groupId>com.aspose</groupId>
                      <artifactId>aspose-pdf</artifactId>
                      <version>23.1</version>
                  </dependency>
                  <dependency>
                      <groupId>com.aspose</groupId>
                      <artifactId>aspose-cells</artifactId>
                      <version>23.1</version>
                  </dependency>
                  <dependency>
                      <groupId>com.aspose</groupId>
                      <artifactId>aspose-slides</artifactId>
                      <version>23.1</version>
                  </dependency>
          

          2 、poi + pdfbox

          因為aspose和spire雖然好用,但是都是是商用組件,所以這里也提供使用開源庫操作的方式的方式。

          POI是Apache軟件基金會用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程序對Microsoft Office格式檔案讀和寫的功能。

          Apache PDFBox是一個開源Java庫,支持PDF文檔的開發和轉換。 使用此庫,您可以開發用于創建,轉換和操作PDF文檔的Java程序。

          需要在項目的pom文件里添加如下依賴

          		<dependency>
                      <groupId>org.apache.pdfbox</groupId>
                      <artifactId>pdfbox</artifactId>
                      <version>2.0.4</version>
                  </dependency>
          		<dependency>
                      <groupId>org.apache.poi</groupId>
                      <artifactId>poi</artifactId>
                      <version>5.2.0</version>
                  </dependency>
                  <dependency>
                      <groupId>org.apache.poi</groupId>
                      <artifactId>poi-ooxml</artifactId>
                      <version>5.2.0</version>
                  </dependency>
                  <dependency>
                      <groupId>org.apache.poi</groupId>
                      <artifactId>poi-scratchpad</artifactId>
                      <version>5.2.0</version>
                  </dependency>
                  <dependency>
                      <groupId>org.apache.poi</groupId>
                      <artifactId>poi-excelant</artifactId>
                      <version>5.2.0</version>
                  </dependency>
          

          3 spire

          spire一款專業的Office編程組件,涵蓋了對Word、Excel、PPT、PDF等文件的讀寫、編輯、查看功能。spire提供免費版本,但是存在只能導出前3頁以及只能導出前500行的限制,只要達到其一就會觸發限制。需要超出前3頁以及只能導出前500行的限制的這需要購買付費版(尊重版權,遠離破解版)。這里使用免費版進行演示。

          spire在添加pom之前還得先添加maven倉庫來源

          		<repository>
                      <id>com.e-iceblue</id>
                      <name>e-iceblue</name>
                      <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
                  </repository>
          

          接著在項目的pom文件里添加如下依賴

          免費版:

          		<dependency>
                      <groupId>e-iceblue</groupId>
                      <artifactId>spire.office.free</artifactId>
                      <version>5.3.1</version>
                  </dependency>
          

          付費版版:

          		<dependency>
                      <groupId>e-iceblue</groupId>
                      <artifactId>spire.office</artifactId>
                      <version>5.3.1</version>
                  </dependency>
          

          二、將文件轉換成html字符串

          1、將word文件轉成html字符串

          1.1 使用aspose

          public static String wordToHtmlStr(String wordPath) {
                  try {
                      Document doc=new Document(wordPath); // Address是將要被轉化的word文檔
                      String htmlStr=doc.toString();
                      return htmlStr;
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
                  return null;
              }
          

          驗證結果:

          1.2 使用poi

          public String wordToHtmlStr(String wordPath) throws TransformerException, IOException, ParserConfigurationException {
                  String htmlStr=null;
                  String ext=wordPath.substring(wordPath.lastIndexOf("."));
                  if (ext.equals(".docx")) {
                      htmlStr=word2007ToHtmlStr(wordPath);
                  } else if (ext.equals(".doc")){
                      htmlStr=word2003ToHtmlStr(wordPath);
                  } else {
                      throw new RuntimeException("文件格式不正確");
                  }
                  return htmlStr;
              }
          
              public String word2007ToHtmlStr(String wordPath) throws IOException {
                  // 使用內存輸出流
                  try(ByteArrayOutputStream out=new ByteArrayOutputStream()){
                      word2007ToHtmlOutputStream(wordPath, out);
                      return out.toString();
                  }
              }
          
              private void word2007ToHtmlOutputStream(String wordPath,OutputStream out) throws IOException {
                  ZipSecureFile.setMinInflateRatio(-1.0d);
                  InputStream in=Files.newInputStream(Paths.get(wordPath));
                  XWPFDocument document=new XWPFDocument(in);
                  XHTMLOptions options=XHTMLOptions.create().setIgnoreStylesIfUnused(false).setImageManager(new Base64EmbedImgManager());
                  // 使用內存輸出流
                  XHTMLConverter.getInstance().convert(document, out, options);
              }
          
          
              private String word2003ToHtmlStr(String wordPath) throws TransformerException, IOException, ParserConfigurationException {
                  org.w3c.dom.Document htmlDocument=word2003ToHtmlDocument(wordPath);
                  // Transform document to string
                  StringWriter writer=new StringWriter();
                  TransformerFactory tf=TransformerFactory.newInstance();
                  Transformer transformer=tf.newTransformer();
                  transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
                  transformer.setOutputProperty(OutputKeys.METHOD, "html");
                  transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                  transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
                  transformer.transform(new DOMSource(htmlDocument), new StreamResult(writer));
                  return writer.toString();
              }
          
          private org.w3c.dom.Document word2003ToHtmlDocument(String wordPath) throws IOException, ParserConfigurationException {
                  InputStream input=Files.newInputStream(Paths.get(wordPath));
                  HWPFDocument wordDocument=new HWPFDocument(input);
                  WordToHtmlConverter wordToHtmlConverter=new WordToHtmlConverter(
                          DocumentBuilderFactory.newInstance().newDocumentBuilder()
                                  .newDocument());
                  wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> {
                      System.out.println(pictureType);
                      if (PictureType.UNKNOWN.equals(pictureType)) {
                          return null;
                      }
                      BufferedImage bufferedImage=ImgUtil.toImage(content);
                      String base64Img=ImgUtil.toBase64(bufferedImage, pictureType.getExtension());
                      //  帶圖片的word,則將圖片轉為base64編碼,保存在一個頁面中
                      StringBuilder sb=(new StringBuilder(base64Img.length() + "data:;base64,".length()).append("data:;base64,").append(base64Img));
                      return sb.toString();
                  });
                  // 解析word文檔
                  wordToHtmlConverter.processDocument(wordDocument);
                  return wordToHtmlConverter.getDocument();
              }

          1.3 使用spire

           public String wordToHtmlStr(String wordPath) throws IOException {
                  try(ByteArrayOutputStream outputStream=new ByteArrayOutputStream()) {
                      Document document=new Document();
                      document.loadFromFile(wordPath);
                      document.saveToFile(outputStream, FileFormat.Html);
                      return outputStream.toString();
                  }
              }

          2、將pdf文件轉成html字符串

          2.1 使用aspose

          public static String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
                  PDDocument document=PDDocument.load(new File(pdfPath));
                  Writer writer=new StringWriter();
                  new PDFDomTree().writeText(document, writer);
                  writer.close();
                  document.close();
                  return writer.toString();
              }

          驗證結果:

          2.2 使用 poi + pbfbox

          public String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
                  PDDocument document=PDDocument.load(new File(pdfPath));
                  Writer writer=new StringWriter();
                  new PDFDomTree().writeText(document, writer);
                  writer.close();
                  document.close();
                  return writer.toString();
              }

          2.3 使用spire

          public String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
                  try(ByteArrayOutputStream outputStream=new ByteArrayOutputStream()) {
                      PdfDocument pdf=new PdfDocument();
                      pdf.loadFromFile(pdfPath);
                      return outputStream.toString();
                  }
              }
          

          3、將excel文件轉成html字符串

          3.1 使用aspose

          public static String excelToHtmlStr(String excelPath) throws Exception {
                  FileInputStream fileInputStream=new FileInputStream(excelPath);
                  Workbook workbook=new XSSFWorkbook(fileInputStream);
                  DataFormatter dataFormatter=new DataFormatter();
                  FormulaEvaluator formulaEvaluator=workbook.getCreationHelper().createFormulaEvaluator();
                  Sheet sheet=workbook.getSheetAt(0);
                  StringBuilder htmlStringBuilder=new StringBuilder();
                  htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
                  htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
                  htmlStringBuilder.append("</head><body><table>");
                  for (Row row : sheet) {
                      htmlStringBuilder.append("<tr>");
                      for (Cell cell : row) {
                          CellType cellType=cell.getCellType();
                          if (cellType==CellType.FORMULA) {
                              formulaEvaluator.evaluateFormulaCell(cell);
                              cellType=cell.getCachedFormulaResultType();
                          }
                          String cellValue=dataFormatter.formatCellValue(cell, formulaEvaluator);
                          htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
                      }
                      htmlStringBuilder.append("</tr>");
                  }
                  htmlStringBuilder.append("</table></body></html>");
                  return htmlStringBuilder.toString();
              }
          

          返回的html字符串:

          <html><head><title>Excel to HTML using Java and POI library</title><style>table, th, td { border: 1px solid black; }</style></head><body><table><tr><td>序號</td><td>姓名</td><td>性別</td><td>聯系方式</td><td>地址</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>1</td><td>張曉玲</td><td>女</td><td>11111111111</td><td>上海市浦東新區xx路xx弄xx號</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦東新區xx路xx弄xx號</td></tr></table></body></html>
          

          3.2 使用poi + pdfbox

          public String excelToHtmlStr(String excelPath) throws Exception {
                  FileInputStream fileInputStream=new FileInputStream(excelPath);
                  try (Workbook workbook=WorkbookFactory.create(new File(excelPath))){
                      DataFormatter dataFormatter=new DataFormatter();
                      FormulaEvaluator formulaEvaluator=workbook.getCreationHelper().createFormulaEvaluator();
                      org.apache.poi.ss.usermodel.Sheet sheet=workbook.getSheetAt(0);
                      StringBuilder htmlStringBuilder=new StringBuilder();
                      htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
                      htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
                      htmlStringBuilder.append("</head><body><table>");
                      for (Row row : sheet) {
                          htmlStringBuilder.append("<tr>");
                          for (Cell cell : row) {
                              CellType cellType=cell.getCellType();
                              if (cellType==CellType.FORMULA) {
                                  formulaEvaluator.evaluateFormulaCell(cell);
                                  cellType=cell.getCachedFormulaResultType();
                              }
                              String cellValue=dataFormatter.formatCellValue(cell, formulaEvaluator);
                              htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
                          }
                          htmlStringBuilder.append("</tr>");
                      }
                      htmlStringBuilder.append("</table></body></html>");
                      return htmlStringBuilder.toString();
                  }
              }
          

          3.3 使用spire

          public String excelToHtmlStr(String excelPath) throws Exception {
                  try(ByteArrayOutputStream outputStream=new ByteArrayOutputStream()) {
                      Workbook workbook=new Workbook();
                      workbook.loadFromFile(excelPath);
                      workbook.saveToStream(outputStream, com.spire.xls.FileFormat.HTML);
                      return outputStream.toString();
                  }
              }
          

          三、將文件轉換成html,并生成html文件

          有時我們是需要的不僅僅返回html字符串,而是需要生成一個html文件這時應該怎么做呢?一個改動量小的做法就是使用org.apache.commons.io包下的FileUtils工具類寫入目標地址:

          FileUtils類將html字符串生成html文件示例:

          首先需要引入pom:

          		<dependency>
                      <groupId>commons-io</groupId>
                      <artifactId>commons-io</artifactId>
                      <version>2.8.0</version>
                  </dependency>
          

          相關代碼:

          String htmlStr=FileConvertUtil.pdfToHtmlStr("D:\\書籍\\電子書\\小說\\歷史小說\\最后的可汗.doc");
          FileUtils.write(new File("D:\\test\\doc.html"), htmlStr, "utf-8");
          

          除此之外,還可以對上面的代碼進行一些調整,已實現生成html文件,代碼調整如下:

          1、將word文件轉換成html文件

          word原文件效果:

          1.1 使用aspose

          public static void wordToHtml(String wordPath, String htmlPath) {
                  try {
                      File sourceFile=new File(wordPath);
                      String path=htmlPath + File.separator + sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf(".")) + ".html";
                      File file=new File(path); // 新建一個空白pdf文檔
                      FileOutputStream os=new FileOutputStream(file);
                      Document doc=new Document(wordPath); // Address是將要被轉化的word文檔
                      HtmlSaveOptions options=new HtmlSaveOptions();
                      options.setExportImagesAsBase64(true);
                      options.setExportRelativeFontSize(true);
                      doc.save(os, options);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          

          轉換成html的效果:

          1.2 使用poi + pdfbox

          public void wordToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
                  htmlPath=FileUtil.getNewFileFullPath(wordPath, htmlPath, "html");
                  String ext=wordPath.substring(wordPath.lastIndexOf("."));
                  if (ext.equals(".docx")) {
                      word2007ToHtml(wordPath, htmlPath);
                  } else if (ext.equals(".doc")){
                      word2003ToHtml(wordPath, htmlPath);
                  } else {
                      throw new RuntimeException("文件格式不正確");
                  }
              }
          
              public void word2007ToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
                  //try(OutputStream out=Files.newOutputStream(Paths.get(path))){
                  try(FileOutputStream out=new FileOutputStream(htmlPath)){
                      word2007ToHtmlOutputStream(wordPath, out);
                  }
              }
          
              private void word2007ToHtmlOutputStream(String wordPath,OutputStream out) throws IOException {
                  ZipSecureFile.setMinInflateRatio(-1.0d);
                  InputStream in=Files.newInputStream(Paths.get(wordPath));
                  XWPFDocument document=new XWPFDocument(in);
                  XHTMLOptions options=XHTMLOptions.create().setIgnoreStylesIfUnused(false).setImageManager(new Base64EmbedImgManager());
                  // 使用內存輸出流
                  XHTMLConverter.getInstance().convert(document, out, options);
              }
          
              public void word2003ToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
                  org.w3c.dom.Document htmlDocument=word2003ToHtmlDocument(wordPath);
                  // 生成html文件地址
          
                  try(OutputStream outStream=Files.newOutputStream(Paths.get(htmlPath))){
                      DOMSource domSource=new DOMSource(htmlDocument);
                      StreamResult streamResult=new StreamResult(outStream);
                      TransformerFactory factory=TransformerFactory.newInstance();
                      Transformer serializer=factory.newTransformer();
                      serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
                      serializer.setOutputProperty(OutputKeys.INDENT, "yes");
                      serializer.setOutputProperty(OutputKeys.METHOD, "html");
                      serializer.transform(domSource, streamResult);
                  }
              }
          
              private org.w3c.dom.Document word2003ToHtmlDocument(String wordPath) throws IOException, ParserConfigurationException {
                  InputStream input=Files.newInputStream(Paths.get(wordPath));
                  HWPFDocument wordDocument=new HWPFDocument(input);
                  WordToHtmlConverter wordToHtmlConverter=new WordToHtmlConverter(
                          DocumentBuilderFactory.newInstance().newDocumentBuilder()
                                  .newDocument());
                  wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> {
                      System.out.println(pictureType);
                      if (PictureType.UNKNOWN.equals(pictureType)) {
                          return null;
                      }
                      BufferedImage bufferedImage=ImgUtil.toImage(content);
                      String base64Img=ImgUtil.toBase64(bufferedImage, pictureType.getExtension());
                      //  帶圖片的word,則將圖片轉為base64編碼,保存在一個頁面中
                      StringBuilder sb=(new StringBuilder(base64Img.length() + "data:;base64,".length()).append("data:;base64,").append(base64Img));
                      return sb.toString();
                  });
                  // 解析word文檔
                  wordToHtmlConverter.processDocument(wordDocument);
                  return wordToHtmlConverter.getDocument();
              }
          

          轉換成html的效果:

          1.3 使用spire

          public void wordToHtml(String wordPath, String htmlPath) {
                  htmlPath=FileUtil.getNewFileFullPath(wordPath, htmlPath, "html");
                  Document document=new Document();
                  document.loadFromFile(wordPath);
                  document.saveToFile(htmlPath, FileFormat.Html);
              }
          

          轉換成html的效果:

          因為使用的是免費版,存在頁數和字數限制,需要完整功能的的可以選擇付費版本。PS:這回76頁的文檔居然轉成功了前50頁。

          2、將pdf文件轉換成html文件

          圖片版pdf原文件效果:

          文字版pdf原文件效果:

          2.1 使用aspose

          public static void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
                  File file=new File(pdfPath);
                  String path=htmlPath + File.separator + file.getName().substring(0, file.getName().lastIndexOf(".")) + ".html";
                  PDDocument document=PDDocument.load(new File(pdfPath));
                  Writer writer=new PrintWriter(path, "UTF-8");
                  new PDFDomTree().writeText(document, writer);
                  writer.close();
                  document.close();
              }
          

          圖片版PDF文件驗證結果:

          文字版PDF文件驗證結果:

          2.2 使用poi + pdfbox

          public void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
                  String path=FileUtil.getNewFileFullPath(pdfPath, htmlPath, "html");
                  PDDocument document=PDDocument.load(new File(pdfPath));
                  Writer writer=new PrintWriter(path, "UTF-8");
                  new PDFDomTree().writeText(document, writer);
                  writer.close();
                  document.close();
              }
          

          圖片版PDF文件驗證結果:

          文字版PDF原文件效果:

          2.3 使用spire

          public void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
                  htmlPath=FileUtil.getNewFileFullPath(pdfPath, htmlPath, "html");
                  PdfDocument pdf=new PdfDocument();
                  pdf.loadFromFile(pdfPath);
                  pdf.saveToFile(htmlPath, com.spire.pdf.FileFormat.HTML);
              }
          

          圖片版PDF文件驗證結果:
          因為使用的是免費版,所以只有前三頁是正常的。。。有超過三頁需求的可以選擇付費版本。

          文字版PDF原文件效果:

          報錯了無法轉換。。。

          java.lang.NullPointerException
          	at com.spire.pdf.PdfPageWidget.spr┢?(Unknown Source)
          	at com.spire.pdf.PdfPageWidget.getSize(Unknown Source)
          	at com.spire.pdf.PdfPageBase.spr???—(Unknown Source)
          	at com.spire.pdf.PdfPageBase.getActualSize(Unknown Source)
          	at com.spire.pdf.PdfPageBase.getSection(Unknown Source)
          	at com.spire.pdf.general.PdfDestination.spr︻┎?—(Unknown Source)
          	at com.spire.pdf.general.PdfDestination.spr┻┑?—(Unknown Source)
          	at com.spire.pdf.general.PdfDestination.getElement(Unknown Source)
          	at com.spire.pdf.primitives.PdfDictionary.setProperty(Unknown Source)
          	at com.spire.pdf.bookmarks.PdfBookmark.setDestination(Unknown Source)
          	at com.spire.pdf.bookmarks.PdfBookmarkWidget.spr┭┘?—(Unknown Source)
          	at com.spire.pdf.bookmarks.PdfBookmarkWidget.getDestination(Unknown Source)
          	at com.spire.pdf.PdfDocumentBase.spr??(Unknown Source)
          	at com.spire.pdf.widget.PdfPageCollection.spr┦?(Unknown Source)
          	at com.spire.pdf.widget.PdfPageCollection.removeAt(Unknown Source)
          	at com.spire.pdf.PdfDocumentBase.spr┞?(Unknown Source)
          	at com.spire.pdf.PdfDocument.loadFromFile(Unknown Source)
          

          3、將excel文件轉換成html文件

          excel原文件效果:

          3.1 使用aspose

          public void excelToHtml(String excelPath, String htmlPath) throws Exception {
                  htmlPath=FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
                  Workbook workbook=new Workbook(excelPath);
                  com.aspose.cells.HtmlSaveOptions options=new com.aspose.cells.HtmlSaveOptions();
                  workbook.save(htmlPath, options);
              }
          

          轉換成html的效果:

          3.2 使用poi

          public void excelToHtml(String excelPath, String htmlPath) throws Exception {
                  String path=FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
                  try(FileOutputStream fileOutputStream=new FileOutputStream(path)){
                      String htmlStr=excelToHtmlStr(excelPath);
                      byte[] bytes=htmlStr.getBytes();
                      fileOutputStream.write(bytes);
                  }
              }
          
          
              public String excelToHtmlStr(String excelPath) throws Exception {
                  FileInputStream fileInputStream=new FileInputStream(excelPath);
                  try (Workbook workbook=WorkbookFactory.create(new File(excelPath))){
                      DataFormatter dataFormatter=new DataFormatter();
                      FormulaEvaluator formulaEvaluator=workbook.getCreationHelper().createFormulaEvaluator();
                      org.apache.poi.ss.usermodel.Sheet sheet=workbook.getSheetAt(0);
                      StringBuilder htmlStringBuilder=new StringBuilder();
                      htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
                      htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
                      htmlStringBuilder.append("</head><body><table>");
                      for (Row row : sheet) {
                          htmlStringBuilder.append("<tr>");
                          for (Cell cell : row) {
                              CellType cellType=cell.getCellType();
                              if (cellType==CellType.FORMULA) {
                                  formulaEvaluator.evaluateFormulaCell(cell);
                                  cellType=cell.getCachedFormulaResultType();
                              }
                              String cellValue=dataFormatter.formatCellValue(cell, formulaEvaluator);
                              htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
                          }
                          htmlStringBuilder.append("</tr>");
                      }
                      htmlStringBuilder.append("</table></body></html>");
                      return htmlStringBuilder.toString();
                  }
              }
          

          轉換成html的效果:

          3.3 使用spire

          public void excelToHtml(String excelPath, String htmlPath) throws Exception {
                  htmlPath=FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
                  Workbook workbook=new Workbook();
                  workbook.loadFromFile(excelPath);
                  workbook.saveToFile(htmlPath, com.spire.xls.FileFormat.HTML);
              }
          

          轉換成html的效果:

          四、總結

          從上述的效果展示我們可以發現其實轉成html效果不是太理想,很多細節樣式沒有還原,這其實是因為這類轉換往往都是追求目標是通過使用文檔中的語義信息并忽略其他細節來生成簡單干凈的 HTML,所以在轉換過程中復雜樣式被忽略,比如居中、首行縮進、字體,文本大小,顏色。舉個例子在轉換是 會將應用標題 1 樣式的任何段落轉換為 h1 元素,而不是嘗試完全復制標題的樣式。所以轉成html的顯示效果往往和原文檔不太一樣。這意味著對于較復雜的文檔而言,這種轉換不太可能是完美的。但如果都是只使用簡單樣式文檔或者對文檔樣式不太關心的這種方式也不妨一試。

          PS:如果想要展示效果好的話,其實可以將上篇文章《文檔在線預覽(一)通過將txt、word、pdf轉成圖片實現在線預覽功能》說的內容和本文結合起來使用,即將文檔里的內容都生成成圖片(很可能是多張圖片),然后將生成的圖片全都放到一個html頁面里 ,用html+css來保持樣式并實現多張圖片展示,再將html返回。開源組件kkfilevie就是用的就是這種做法。

          kkfileview展示效果如下:

          下圖是kkfileview返回的html代碼,從html代碼我們可以看到kkfileview其實是將文件(txt文件除外)每頁的內容都轉成了圖片,然后將這些圖片都嵌入到一個html里,再返回給用戶一個html頁面。


          主站蜘蛛池模板: 亚洲日韩精品一区二区三区| 无码中文人妻在线一区二区三区| 日本在线不卡一区| 中文字幕视频一区| 亚洲一区无码精品色| 99久久精品午夜一区二区| 中文乱码精品一区二区三区 | 精品国产AⅤ一区二区三区4区| 国产吧一区在线视频| 久久精品免费一区二区三区| 精品成人av一区二区三区| 精品一区二区三区水蜜桃| 欧洲精品码一区二区三区| 乱精品一区字幕二区| 久久无码人妻一区二区三区 | 精品视频一区二区三区四区五区| 免费看AV毛片一区二区三区| 日韩中文字幕精品免费一区| 91在线看片一区国产| 亚洲国产激情在线一区| 日韩一区二区三区四区不卡| 国产电影一区二区| 伊人无码精品久久一区二区| 亚洲另类无码一区二区三区| 欧美成人aaa片一区国产精品| 欧美成人aaa片一区国产精品 | 91一区二区在线观看精品| 亚洲一区在线视频观看| 3d动漫精品啪啪一区二区中文| 国产福利一区二区三区在线观看 | bt7086福利一区国产| 亚洲av无码一区二区三区四区| 天堂一区人妻无码| 国产一区二区三区小向美奈子| 丰满岳乱妇一区二区三区| 久久影院亚洲一区| 人妻夜夜爽天天爽爽一区| 亚洲av乱码中文一区二区三区 | 一区二区三区日本视频| 手机看片福利一区二区三区| 91亚洲一区二区在线观看不卡|