整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          Ueditor二次編輯word(doc和docx格式),SpringBoot后端

          ue+ueditor+springboot, 實現(xiàn)word文檔上傳編輯

          前言

          `前端導入word文檔(doc和docx格式都支持),Ueditor富文本回顯進行二次編輯,目前ueditor項目archived了,實現(xiàn)兩種格式的相關材料相對稀缺。

          `解決思路:

          1.上傳word文件

          2.后臺讀取word內容(圖片需要額外處理保存到服務器固定的地址,該地址能讓瀏覽器直接訪問),生成html文件

          3.后臺讀取html文件內容返回給前端


          一、目標

          通過上傳word文件,通過后臺進行解析回顯到前端。



          二、代碼步驟

          后端代碼結構:


          1.maven依賴庫

          <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi</artifactId>
          <version>3.15</version>
          </dependency>
          <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi-ooxml</artifactId>
          <version>3.15</version>
          </dependency>
          <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi-ooxml-schemas</artifactId>
          <version>3.15</version>
          </dependency>
          <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi-scratchpad</artifactId>
          <version>3.15</version>
          </dependency>
          <dependency>
          <groupId>fr.opensagres.xdocreport</groupId>
          <artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
          <version>1.0.6</version>
          </dependency>

          2.vue頁面讀取ueditor的配置

          代碼如下:

          /**
          * 獲取UE文件上傳配置
          * @param request
          * @param response
          * @throws IOException
          */
          @GetMapping(value = "/config")
          public void ueConfig(HttpServletRequest request, HttpServletResponse response) throws IOException {
          response.setContentType("application/json");
          response.setCharacterEncoding("utf-8");
          String urlPrefix = ueProperties.getSavepath();
          log.info("urlPrefix = "+urlPrefix);
          String exec = "{\n" +
          " /* 上傳圖片配置項 */\n" +
          " \"imageActionName\": \"catcherImage\", /* 執(zhí)行上傳圖片的action名稱 */\n" +
          " \"imageFieldName\": \"upfile\", /* 提交的圖片表單名稱 */\n" +
          " \"imageMaxSize\": 2048, /* 上傳大小限制,單位B */\n" +
          " \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 上傳圖片格式顯示 */\n" +
          " \"imageCompressEnable\": true, /* 是否壓縮圖片,默認是true */\n" +
          " \"imageCompressBorder\": 800, /* 圖片壓縮最長邊限制 */\n" +
          " \"imageInsertAlign\": \"none\", /* 插入的圖片浮動方式 */\n" +
          " \"imageUrlPrefix\": \"" + urlPrefix + "\", /* 圖片訪問路徑前綴 */\n" +
          " \"imagePathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " /* {filename} 會替換成原文件名,配置這項需要注意中文亂碼問題 */\n" +
          " /* {rand:6} 會替換成隨機數(shù),后面的數(shù)字是隨機數(shù)的位數(shù) */\n" +
          " /* {time} 會替換成時間戳 */\n" +
          " /* {yyyy} 會替換成四位年份 */\n" +
          " /* {yy} 會替換成兩位年份 */\n" +
          " /* {mm} 會替換成兩位月份 */\n" +
          " /* {dd} 會替換成兩位日期 */\n" +
          " /* {hh} 會替換成兩位小時 */\n" +
          " /* {ii} 會替換成兩位分鐘 */\n" +
          " /* {ss} 會替換成兩位秒 */\n" +
          " /* 非法字符 \\ : * ? \" < > | */\n" +
          " /* 具請體看線上文檔: fex.baidu.com/ueditor/#use-format_upload_filename */\n" +
          "\n" +
          " /* 涂鴉圖片上傳配置項 */\n" +
          " \"scrawlActionName\": \"uploadscrawl\", /* 執(zhí)行上傳涂鴉的action名稱 */\n" +
          " \"scrawlFieldName\": \"upfile\", /* 提交的圖片表單名稱 */\n" +
          " \"scrawlPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"scrawlMaxSize\": 2048000, /* 上傳大小限制,單位B */\n" +
          " \"scrawlUrlPrefix\": \"\", /* 圖片訪問路徑前綴 */\n" +
          " \"scrawlInsertAlign\": \"none\",\n" +
          "\n" +
          " /* 截圖工具上傳 */\n" +
          " \"snapscreenActionName\": \"uploadimage\", /* 執(zhí)行上傳截圖的action名稱 */\n" +
          " \"snapscreenPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"snapscreenUrlPrefix\": \"\", /* 圖片訪問路徑前綴 */\n" +
          " \"snapscreenInsertAlign\": \"none\", /* 插入的圖片浮動方式 */\n" +
          "\n" +
          " /* 抓取遠程圖片配置 */\n" +
          " \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n" +
          " \"catcherActionName\": \"catchimage\", /* 執(zhí)行抓取遠程圖片的action名稱 */\n" +
          " \"catcherFieldName\": \"source\", /* 提交的圖片列表表單名稱 */\n" +
          " \"catcherPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"catcherUrlPrefix\": \"" + urlPrefix + "\", /* 圖片訪問路徑前綴 */\n" +
          " \"catcherMaxSize\": 2048000, /* 上傳大小限制,單位B */\n" +
          " \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 抓取圖片格式顯示 */\n" +
          "\n" +
          " /* 上傳視頻配置 */\n" +
          " \"videoActionName\": \"uploadvideo\", /* 執(zhí)行上傳視頻的action名稱 */\n" +
          " \"videoFieldName\": \"upfile\", /* 提交的視頻表單名稱 */\n" +
          " \"videoPathFormat\": \"/ueditor/video/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"videoUrlPrefix\": \"\", /* 視頻訪問路徑前綴 */\n" +
          " \"videoMaxSize\": 10240000, /* 上傳大小限制,單位B,默認10MB */\n" +
          " \"videoAllowFiles\": [\n" +
          " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
          " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\"], /* 上傳視頻格式顯示 */\n" +
          " /* 上傳文件配置 */\n" +
          " \"fileActionName\": \"uploadfile\", /* controller里,執(zhí)行上傳視頻的action名稱 */\n" +
          " \"fileFieldName\": \"upfile\", /* 提交的文件表單名稱 */\n" +
          " \"filePathFormat\": \"/ueditor/file/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"fileUrlPrefix\": \"\", /* 文件訪問路徑前綴 */\n" +
          " \"fileMaxSize\": 10240000, /* 上傳大小限制,單位B,默認10MB */\n" +
          " \"fileAllowFiles\": [\n" +
          " \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
          " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
          " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
          " \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
          " \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
          " ], /* 上傳文件格式顯示 */\n" +
          " /* 列出指定目錄下的圖片 */\n" +
          " \"imageManagerActionName\": \"listimage\", /* 執(zhí)行圖片管理的action名稱 */\n" +
          " \"imageManagerListPath\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 指定要列出圖片的目錄 */\n" +
          " \"imageManagerListSize\": 20, /* 每次列出文件數(shù)量 */\n" +
          " \"imageManagerUrlPrefix\": \"" + urlPrefix + "\", /* 圖片訪問路徑前綴 */\n" +
          " \"imageManagerInsertAlign\": \"none\", /* 插入的圖片浮動方式 */\n" +
          " \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 列出的文件類型 */\n" +
          " /* 列出指定目錄下的文件 */\n" +
          " \"fileManagerActionName\": \"listfile\", /* 執(zhí)行文件管理的action名稱 */\n" +
          " \"fileManagerListPath\": \"/ueditor/file/{yyyy}{mm}{dd}/\", /* 指定要列出文件的目錄 */\n" +
          " \"fileManagerUrlPrefix\": \"\", /* 文件訪問路徑前綴 */\n" +
          " \"fileManagerListSize\": 20, /* 每次列出文件數(shù)量 */\n" +
          " \"fileManagerAllowFiles\": [\n" +
          " \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
          " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
          " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
          " \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
          " \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
          " ] /* 列出的文件類型 */\n" +
          "}";
          PrintWriter writer = response.getWriter();
          writer.write(exec);
          writer.flush();
          writer.close();
          }

          ```

          3.前端導入文件

          代碼如下:

          methods: {
          ready(editorInstance) {
            this.editorInstance=editorInstance
            async uploadWordFile(event) {
            const file = event.target.files[0];
            if (!file) return;
            // 將Word文件轉換為HTML
            const htmlContent = await this.convertWordToHtml(file);
            const jsonData = JSON.parse(htmlContent)
            // 設置UEditor的內容
            console.log(jsonData)
            this.editorInstance.execCommand('inserthtml',jsonData.data)
          },
          async convertWordToHtml(wordFile) {
            // 這里應該是Word文件轉HTML的后端接口調用代碼
            // 假設有一個轉換Word為HTML的后端API
            const formData = new FormData();
            formData.append('file', wordFile);
            const response = await fetch('/api/ue/uploadFile',{
            method:'POST',
            body:formData
          })
          if (response.ok) {
          	return await response.text();
          }
          throw new Error('轉換失敗');
          }
          }


          4.后端讀取文件生成html

          代碼如下:

          
          /** word文檔上傳
          *
          * @param file
          * @return
          */
          @PostMapping("/uploadFile")
          public Object uploadFile(@RequestParam(name = "file") MultipartFile file){
            String filename = file.getOriginalFilename();
            JSONObject result = new JSONObject();
            String visitHtml = "";
            try {
              if (filename.endsWith(".docx")) {
              //TODO 處理docx格式的
              visitHtml = WordConverHtmlUtils.docxToHtmlText(file, ueProperties);
              } else if (filename.endsWith(".doc")) {
              //TODO 處理doc格式的
              visitHtml = WordConverHtmlUtils.docToHtmlText(file, ueProperties);
            } else {
            	log.error("不支持的文件格式!");
            }
            result.put("state", "SUCCESS");
            result.put("data", visitHtml);
            log.info("result: {}", result.toString());
            } catch (Exception e) {
           		 log.error("文件找不到異常!");
            	 e.printStackTrace();
            }
            return result;
          }

          5.WordConverHtmlUtils工具類

          ??????????

          options.URIResolver(new BasicURIResolver(picUri));

          picUri地址,必須能通過瀏覽器直接訪問,否則編輯器中無法渲染出來圖片; 比如作者:http://localhost:8000/resource/ueditor/file/20240404/1712220732312.png(本地搭建NG測試)

          ??????????

          代碼如下:
          package com.ue.demo.utils;
          import cn.hutool.core.lang.UUID;
          import com.ue.demo.config.UeProperties;
          import lombok.extern.slf4j.Slf4j;
          import org.apache.poi.hwpf.HWPFDocument;
          import org.apache.poi.hwpf.converter.PicturesManager;
          import org.apache.poi.hwpf.converter.WordToHtmlConverter;
          import org.apache.poi.hwpf.usermodel.PictureType;
          import org.apache.poi.xwpf.converter.core.BasicURIResolver;
          import org.apache.poi.xwpf.converter.core.FileImageExtractor;
          import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
          import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
          import org.apache.poi.xwpf.usermodel.XWPFDocument;
          import org.springframework.web.multipart.MultipartFile;
          import org.w3c.dom.Document;
          import javax.xml.parsers.DocumentBuilderFactory;
          import javax.xml.transform.OutputKeys;
          import javax.xml.transform.Transformer;
          import javax.xml.transform.TransformerFactory;
          import javax.xml.transform.dom.DOMSource;
          import javax.xml.transform.stream.StreamResult;
          import java.io.*;
          import java.nio.file.Files;
          import java.nio.file.Path;
          import java.nio.file.Paths;
          /**
          * @author:Peanut
          * @create: 2024-04-05 10:22
          * @version: 1.0.0
          * @description:
          */
          @Slf4j
            public class WordConverHtmlUtils {
                  private final static String FILE_URL_PRE = "/ueditor/file/";
                  /**
                  * 上傳docx文檔,返回解析后的Html
                  */
                  public static String docxToHtmlText(MultipartFile file, UeProperties ueProperties) throws Exception {
                  try {
                  String fileName = UUID.fastUUID().toString();
                  //圖片存放地址
                  String imagePath = ueProperties.getSavepath().concat(FILE_URL_PRE).concat("/");
                  String fileOutName = imagePath.concat(fileName).concat(".html");
                  log.info("上傳docx文檔解析");
                  log.info("上傳docx文檔,返回解析后的Html, imagePath:{}", imagePath);
                  log.info("fileOutName:{}", fileOutName);
                  //獲取一個用操作Word的對象
                  XWPFDocument document = new XWPFDocument(file.getInputStream());
                  //導出為html時的一些基本設置類
                  XHTMLOptions options = null;
                  //判斷word文件中是否有圖片
                  if(document.getAllPictures().size() > 0) {
                  //獲取默認的對象,設置縮進indent
                  options = XHTMLOptions.getDefault().indent(4);
                  // 如果包含圖片的話,要設置圖片的導出位置
                  File imageFolder = new File(imagePath);
                  //設置圖片抽取器的目的地文件夾 用于存放圖片文件
                  options.setExtractor(new FileImageExtractor(imageFolder));
                  // URI resolver word的html中圖片的目錄路徑
                  //??????????????????????????????????
                  //?????????? 這里需要設置為前端能過直接訪問到的圖片地址, 比如作者:http://localhost:8000/resource/ueditor/file/20240404/1712220732312.png,
                  //?????????? 否則,ueditor編輯器無法顯示word文檔中的圖片
                  String picUri = ueProperties.getShowpath().concat(imagePath.substring(imagePath.indexOf("ueditor")));
                  options.URIResolver(new BasicURIResolver(picUri));
                }
                //獲取輸出的html文件對象
                File outFile = new File(fileOutName);
                if(!outFile.getParentFile().exists()){
                outFile.getParentFile().mkdirs();
                }
                //創(chuàng)建所有的父路徑,如果不存在父目錄的話
                outFile.getParentFile().mkdirs();
                //創(chuàng)建一個輸出流
                OutputStream out = new FileOutputStream(outFile);
                //html轉換器
                XHTMLConverter.getInstance().convert(document, out, options);
                log.info("html轉換器 success");
                //處理生成的html,字符串形式給前端
                return readHtmlStr(fileOutName);
                } catch (Exception e) {
                log.error("docxToHtmlText 解析異常", e);
                }
                return "";
          }
          /**
          * 上傳doc格式Word文檔,返回解析后的Html
          * @param file
          * @param ueProperties
          * @return
          * @throws Exception
          */
          public static String docToHtmlText(MultipartFile file, UeProperties ueProperties) throws Exception {
                //使用字符數(shù)組流獲取解析的內容
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                OutputStream outStream = new BufferedOutputStream(baos);
                try {
                String fileName = UUID.fastUUID().toString();
                //將上傳的文件傳入Document轉換
                //圖片存放地址
                String docPath = ueProperties.getSavepath().concat(FILE_URL_PRE).concat("/");
                String imagePath = docPath.concat("image/");
                String fileOutName = docPath.concat(fileName).concat(".html");
                log.info("上傳doc文檔,返回解析 ");
                log.info("fileOutName:{}", fileOutName);
                //創(chuàng)建圖片文件的存儲目錄
                new File(imagePath).mkdirs();
                //poi中doc文檔對應的實體類
                HWPFDocument hwpfDocument = new HWPFDocument(file.getInputStream());
                //使用空的文檔對象構建一個轉換對象
                WordToHtmlConverter converter = new WordToHtmlConverter(DocumentBuilderFactory
                .newInstance()
                .newDocumentBuilder()
                .newDocument());
                //設置存儲圖片的管理者--使用匿名內部類實現(xiàn) 該類實現(xiàn)了PicturesManager接口,實現(xiàn)了其中的savePicture方法
                converter.setPicturesManager(new PicturesManager() {
                FileOutputStream out = null;
                //在下面的processDocument方法內部會調用該方法 用于存儲word中的圖片文件
                @Override
                public String savePicture(byte[] bytes, PictureType pictureType, String name, float width, float height) {
                try {
                //單個照片的保存
                out = new FileOutputStream(imagePath + name);
                out.write(bytes);
                } catch (IOException exception) {
                exception.printStackTrace();
                }finally {
                if(out != null) {
                try {
                out.close();
                } catch (IOException e) {
                e.printStackTrace();
                }
                }
          }
          //這里要返回給操作者(HtmlDocumentFacade)一個存儲的路徑 用于生成Html時定位到圖片資源
          //??????????????????????????????????
          //?????????? 這里需要設置為前端能過直接訪問到的圖片地址, 比如作者:http://localhost:8000/resource/ueditor/file/20240404/1712220732312.png,
          //?????????? 否則,ueditor編輯器無法顯示word文檔中的圖片
          			return ueProperties.getShowpath().concat(imagePath.substring(imagePath.indexOf("ueditor"))).concat(name);
                }
                });
                //使用外觀模式,將hwpfDocument文檔對象設置給HtmlDocumentFacade中的Document屬性
                converter.processDocument(hwpfDocument);
                //獲取轉換器中的document文檔
                Document htmlDocument = converter.getDocument();
                //充當文檔對象模型 (DOM) 樹形式的轉換源樹的持有者 -- 源樹
                DOMSource domSource = new DOMSource(htmlDocument);
                //轉換器 該對象用于將源樹轉換為結果樹
                Transformer transformer = TransformerFactory.newInstance().newTransformer();
                //設置輸出時的以什么方式輸出,也可說是結果樹的文件類型 可以是html/xml/text或者是一些擴展前三者的擴展類型
                transformer.setOutputProperty(OutputKeys.METHOD , "html");
                //設置一些必要的屬性 設置輸出時候的編碼為utf-8
                transformer.setOutputProperty(OutputKeys.ENCODING , "utf-8");
                //轉換 將輸入的源樹轉換為結果樹并且輸出到streamResult中
                transformer.transform(domSource , new StreamResult(new File(fileOutName)));
                log.info("html轉換器 success");
                //處理生成的html,字符串形式給前端
                return readHtmlStr(fileOutName);
                } catch (Exception e) {
                log.error("docToHtmlText 異常", e);
                } finally {
                baos.close();
                outStream.close();
                }
                return null;
          }
          /**
          * 讀取html文件,轉成字符串返回給前端
          * 去除換行,以及連續(xù)兩個空格
          * @param htmlDirPath html文件路徑
          * @return
          * @throws IOException
          */
          private static String readHtmlStr(String htmlDirPath) throws IOException {
          log.info("處理生成的html,字符串形式給前端:{} ...Start..", htmlDirPath);
          String htmlStr = "";
          try {
          Path htmlPath = Paths.get(htmlDirPath);
          htmlStr = new String(Files.readAllBytes(htmlPath));
          htmlStr = htmlStr.replaceAll("\\n", "");
          htmlStr = htmlStr.replaceAll("\\s{2,}", " ");
          log.info("處理生成的html,字符串形式給前端。。。end");
          } catch (IOException e) {
          log.error("處理生成的html,字符串形式出錯了, {}", e.getMessage());
          }
          return htmlStr;
          }
          }


          6.后端配置文件

          代碼如下:

          spring.application.name=ue
          server.port=8000
          ##UE編輯器配置
          #編輯器訪問服務器的圖片地址
          ue.showpath=http://localhost:8000/resource
          #ue文件存儲路徑前綴
          ue.savepath=/Users/cookie/Documents/coding/uedemo
          ```
          !!! ue.showpath=生產上有nginx需要在nginx.conf進行配置


          三、實現(xiàn)效果

          成功通過導入word文章,回顯內容到ueditor編輯器


          總結

          *贈人玫瑰,手留余香*

          源碼地址:

          https://gitee.com/gwancookie/uedemo

          **讀取word文檔生成html借鑒:**

          https://blog.csdn.net/qq_44717657/article/details/124497326

          文以C#及VB.NET后端程序代碼示例展示如何將HTML轉為XML文件。轉換時,調用Word API -Free Spire.Doc for .NET 提供的文檔加載方法及文檔保存的方法來實現(xiàn)。轉換的代碼步驟很簡單,具體可參考以下內容。


          引入dll

          1.通過NuGet安裝dll(2種方法)

          1.1可以在Visual Studio中打開“解決方案資源管理器”,鼠標右鍵點擊“引用”,“管理NuGet包”,然后搜索“Free Spire.Doc”,點擊“安裝”。等待程序安裝完成。

          1.2將以下內容復制到PM控制臺安裝:

          Install-Package FreeSpire.Doc -Version 10.2

          2.手動添加dll引用

          可通過手動下載包到本地,然后解壓,找到BIN文件夾下的Spire.Doc.dll。然后在Visual Studio中打開“解決方案資源管理器”,鼠標右鍵點擊“引用”,“添加引用”,將本地路徑BIN文件夾下的dll文件添加引用至程序。


          將HTML轉為XML

          轉換時,可參考如下代碼來進行:

          1. 創(chuàng)建Document類的對象。
          2. 調用Document.LoadFromFile(string fileName, FileFormat fileFormat)方法加載HTML文檔。
          3. 通過Document.SaveToFile(string fileName, FileFormat fileFormat)方法保存為XML格式到指定路徑。

          C#

          using Spire.Doc;
          
          namespace HTMLtoXML
          {
              class Program
              {
                  static void Main(string[] args)
                  {
                      //創(chuàng)建Document類的對象
                      Document doc = new Document();
          
                      //加載html文件
                      doc.LoadFromFile("sample.html",FileFormat.Html);
          
                      //保存為XML格式
                      doc.SaveToFile("HTMLtoXML.xml", FileFormat.Xml);
                      System.Diagnostics.Process.Start("HTMLtoXML.xml");
                  }
              }
          }

          vb.net

          Imports Spire.Doc
          
          Namespace HTMLtoXML
              Class Program
                  Private Shared Sub Main(args As String())
                      '創(chuàng)建Document類的對象
                      Dim doc As New Document()
          
                      '加載html文件
                      doc.LoadFromFile("sample.html", FileFormat.Html)
          
                      '保存為XML格式
                      doc.SaveToFile("HTMLtoXML.xml", FileFormat.Xml)
                      System.Diagnostics.Process.Start("HTMLtoXML.xml")
                  End Sub
              End Class
          End Namespace

          轉換效果:

          —End—

          大家好,最近在工作中用到了一個不一樣接口文檔生成器,EasyYapi 接口生成器

          下面是來分享給大家如何操作,在idea 編輯器中很方便。

          鏈接:http://easyyapi.com/documents/index.html EasyYapi官方文檔.

          下載插件

          重啟IDEA,配置EasyYapi

          獲取token

          使用

          快捷鍵 Alt+insert

          Java注釋規(guī)范(配合EasyYapi使用)

          api demo
          
          /**
           * 分類名稱
           * 分類備注/描述
           *
           * @module 歸屬項目
           */
          @RestController
          @RequestMapping(value = "/pathOfCtrl")
          public class MockCtrl {
          
              /**
              * api名稱
              * api描述
              * @param param1 參數(shù)1的名稱或描述
              * @param param2 可以用`@link`來表示當前參數(shù)的取值是某個枚舉{@link some.enum.or.constant.class}
              * @param param3 當目標枚舉字段與當前字段名不一致,額外指定{@link some.enum.or.constant.class#property1}
              * @return 響應描述
              */
              @RequestMapping(value = "/pathOfApi1")
              public Result methodName1(long param1,
                                @RequestParam String param2,
                                @RequestParam(required = false, defaultValue = "defaultValueOfParam3") String param3){
                  ...
              }
          
          
              /**
              * 默認使用`application/x-www-form-urlencoded`,
              * 對于`@RequestBody`將使用`application/json`
              * 可以用注解`@Deprecated`來表示api廢棄
              * 也可以用注釋`@deprecated`
              *
              * @deprecated 改用{@link #methodName3(String)}
              */
              @Deprecated
              @RequestMapping(value = "/pathOfApi2")
              public Result methodName2(@RequestBody MockDtoOrVo jsonModel){
                  ...
              }
          
              /**
              * 所有注釋或者參數(shù)描述中都可以使用`@link`來引用另一個API
              * 例如:
              * 請先訪問{@link #methodName4(String)}
          
              * 也可以使用`@see`來引用另一個API
              *
              * @param param1 參數(shù)1的名稱或描述 可以從{@link #methodName5(String)}中獲得
              * @see #methodName6(String)
              * @deprecated 改用{@link #methodName7(String)}
              */
              @Deprecated
              @RequestMapping(value = "/pathOfApi3")
              public Result methodName3(long param1){
                  ...
              }
          
              ...
          }
          model(dto/vo) demo
          public class MockDtoOrVo {
          
              /**
               * 字段注釋
               */
              private Long field1;
          
              private Double field2;//注釋也可以寫在這
          
              /**
               * 使用@see來說明當前字段的取值是某個枚舉
               * @see some.enum.or.constant.class
               */
              private int field3;
          
              /**
               * 當目標枚舉字段與當前字段名不一致,額外指定
               * @see some.enum.or.constant.class#property1
               */
              private int field4;
          
              /**
               * 可以用注解`@Deprecated`來表示字段被廢棄
               * 也可以用注釋`@deprecated`
               * @deprecated It's a secret
               */
              @Deprecated
              private int field5;
          
              /**
               * 如果使用javax.validation的話
               * 可以使用@NotBlank/@NotNull表示字段必須
               */
              @NotBlank
              @NotNull
              private String field6;
          
              ...
          }
          

          可以登錄自己搭建yapi 服務上查看到

          感覺這種方式不用寫swagger 還需要寫配置,當然,看個人和公司想法。

          借鑒:https://blog.csdn.net/qq_41604890/article/details/117299544


          主站蜘蛛池模板: 国产精品亚洲高清一区二区| 色狠狠色狠狠综合一区| 国产乱码一区二区三区四| 国产精品夜色一区二区三区| 人妻精品无码一区二区三区 | 亚洲国模精品一区| 91麻豆精品国产自产在线观看一区| 国产日韩AV免费无码一区二区三区| 无码人妻一区二区三区在线视频| 国产精品一区二区不卡| 国产一区二区视频免费| 日本成人一区二区| 最新中文字幕一区| 色婷婷AV一区二区三区浪潮 | 亚洲片一区二区三区| 精品无码人妻一区二区三区| 日本v片免费一区二区三区 | 亚洲国产成人久久综合一区| 国产精品日韩一区二区三区| 国产伦精品一区二区三区| 成人丝袜激情一区二区| 亚洲日本一区二区三区在线| 精品一区二区三区| 无码国产精品一区二区免费16| 濑亚美莉在线视频一区| 午夜福利av无码一区二区| 免费人妻精品一区二区三区| 91久久精品午夜一区二区| 亚洲AV无码一区二三区| 免费无码A片一区二三区| 久久99国产精品一区二区| 日韩精品一区在线| 久久精品一区二区三区AV| 国产福利电影一区二区三区久久久久成人精品综合 | 国产在线观看一区精品| 亚洲av无码片vr一区二区三区| 中文字幕无线码一区| 久久青青草原一区二区| 乱色精品无码一区二区国产盗| 一区二区三区免费看| 精品久久综合一区二区|