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 草草影院www色极品欧美,午夜精品视频,91精品国产综合久

          整合營(yíng)銷(xiāo)服務(wù)商

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

          免費(fèi)咨詢(xún)熱線(xiàn):

          UEditor-前端使用心得(前后端分離實(shí)踐)

          UEditor-前端使用心得(前后端分離實(shí)踐)

          得差不多就是去年的這個(gè)時(shí)候,我從原來(lái)的單位辭職。原因很簡(jiǎn)單,二十三四歲,正式一個(gè)該奮斗的年紀(jì)。雖然家里的條件可以允許自己不必太努力,但是唯有自己擁有賺更多錢(qián)的能力,才會(huì)讓自己覺(jué)得心安。思來(lái)想去,選擇了繼續(xù)深鉆大學(xué)的專(zhuān)業(yè),至此我的前端之路也正式開(kāi)始了。

          這一年,從學(xué)習(xí)到工作,發(fā)生了很多的事情。其實(shí)自己是一個(gè)比較不愿意寫(xiě)東西的人,寫(xiě)博客這個(gè)念頭也不是一天倆天了,但就是怎么也開(kāi)展不了。直到前幾天,公司的一個(gè)項(xiàng)目需求,要用百度的編輯器UEditor替換掉原來(lái)的富文本編輯器。一個(gè)小小的編輯器,做起來(lái)卻是一個(gè)坑接一個(gè)坑,多虧網(wǎng)上的好心的人把自己的經(jīng)驗(yàn)留下來(lái),才能順利走下來(lái)。感受到這個(gè)互聯(lián)網(wǎng)的共享性和無(wú)私性,我也決定成為大家的其中一員,為大家貢獻(xiàn)出自己踩每一個(gè)坑時(shí)的心路歷程,希望可以幫助大家,同大家一起共同學(xué)習(xí)。

          話(huà)就不多說(shuō)了,走進(jìn)正題。UEditor的使用心得。

          首先將一下我們的項(xiàng)目架構(gòu)。本來(lái)整個(gè)項(xiàng)目是.NET跑的,因?yàn)橐恍┰蛞D(zhuǎn)到JAVA上來(lái),所以目前的項(xiàng)目暫定為.NET來(lái)跑前端,接口方面由JAVA來(lái)提供。因此在使用UEdior時(shí)也是一樣的。

          前期還是比較順利的,照著官方文檔來(lái)做。

          下載的時(shí)候,有點(diǎn)小懵逼,本以為就是一個(gè)前端小插件,怎么還分這來(lái)多版本,鬧啥這是。因?yàn)闀r(shí).net跑的前端,我就下載了.net版

          下載的資源包里有demo,還是比較好理解的

          簡(jiǎn)單的來(lái)說(shuō)就是 1.引倆JS 2.body里加一個(gè)script標(biāo)簽 3.用getEditor方式創(chuàng)建

          跑一下。

          這是用在一個(gè)新聞審核時(shí)的編輯器。所以一開(kāi)始編輯器就會(huì)帶有默認(rèn)值。這里解釋下 我為什么沒(méi)有直接直接將數(shù)據(jù)放在編輯器的script標(biāo)簽中,如果直接讀那么在編輯器中會(huì)顯示一堆字符串而不是轉(zhuǎn)譯后的html,此外有時(shí)還會(huì)出現(xiàn)內(nèi)容展示在編輯器外的bug。

          如果通過(guò)一個(gè)textarea先存放數(shù)據(jù)再用官方文檔中的setContent()方法設(shè)置編輯器的內(nèi)容,就完美解決了??聪滦Ч昝?。

          注:大家在實(shí)際使用的時(shí)候會(huì)遇見(jiàn)雙引號(hào)和單引號(hào)無(wú)法轉(zhuǎn)譯的問(wèn)題。這塊我就附個(gè)鏈接http://blog.csdn.net/wanghao3616/article/details/25816747 照這樣就可以完美解決了

          好了效果實(shí)現(xiàn),重點(diǎn)來(lái)了。圖片上傳。我們具體來(lái)分析下代碼的流程是怎樣的。

          UEdior.all.js這個(gè)主文件我們先不看,先看uedior.config.js這個(gè)配置的文件

          這個(gè)紅框的地方就是后臺(tái)請(qǐng)求的統(tǒng)一接口。官方文檔已經(jīng)說(shuō)了,1.4*版本以后已經(jīng)把所有的后臺(tái)請(qǐng)求接口合并成一個(gè)了,也就是說(shuō)無(wú)論上傳還是涂鴉上傳都是使用這個(gè)接口只是參數(shù)action不一樣。當(dāng)然我在實(shí)際項(xiàng)目的時(shí)候還是任性的把這個(gè)接口拆開(kāi)了。

          這樣比較直觀。其實(shí)比較有用的接口就是前倆個(gè)。在調(diào)試項(xiàng)目的時(shí)候發(fā)現(xiàn),編輯器最先會(huì)發(fā)這個(gè)action='config'的請(qǐng)求。這個(gè)是設(shè)定圖片訪(fǎng)問(wèn)規(guī)則的一些配置。在寫(xiě)這個(gè)接口的時(shí)候出現(xiàn)了一些問(wèn)題,后端返回的數(shù)據(jù)老是存在問(wèn)題,所以我就直接用了項(xiàng)目中基于.net的原始接口調(diào)用前端這邊的config.json文件。其實(shí)我覺(jué)得這個(gè)配置文件放在后端調(diào)用返回給前端來(lái)最好,因?yàn)楹蠖俗钋宄@些請(qǐng)求地址該怎么寫(xiě)。

          因?yàn)楹蠖私涌跊](méi)實(shí)現(xiàn),我就把配置文件放在了前端,之后我把配置中的路徑都設(shè)置為空,這一直接憑后端返回的url就可以直接訪(fǎng)問(wèn)了 不需要再拼了(其實(shí)這樣一來(lái),配置沒(méi)啥個(gè)用了,存粹走個(gè)流程。。)

          配置讀取完就該上傳圖片了。因?yàn)槲覀兊捻?xiàng)目是倆個(gè)服務(wù)器構(gòu)成的所以呢就涉及到了跨域的問(wèn)題。。。這里面是有個(gè)坑的。那就是單圖和多圖的處理是不一樣的。

          多圖比較簡(jiǎn)單

          只要設(shè)置好請(qǐng)求頭之類(lèi)普通的跨域常見(jiàn)問(wèn)題,再調(diào)剛才設(shè)置的圖片上傳接口就OK了

          單圖的話(huà)就比較蛋疼了。單文件上傳是form提交到iframe,然后iframe里面的內(nèi)容返回。官方也說(shuō)了。單文件比較難搞

          解決方案就是讓后端先將數(shù)據(jù)反回給.net服務(wù)器的一個(gè)中轉(zhuǎn)頁(yè)面,再通過(guò)這個(gè)中轉(zhuǎn)頁(yè)面返回來(lái)顯示,這樣就完美解決了單文件的跨域問(wèn)題。

          單文件的請(qǐng)求接口位置 直接修改all.js

          1.修改action就是接口

          2.干掉這行默認(rèn)的url

          搞完這個(gè)就大功告成了。累累累。。。。。

          置于后端代碼。我這個(gè)前端er就不貼了 如果有需要的朋友有需要可以留言和我說(shuō)。

          說(shuō)實(shí)在的純手寫(xiě)這么多,也不知道又沒(méi)人會(huì)看。第一次,以后也會(huì)把質(zhì)量提起來(lái)。自己也會(huì)堅(jiān)持寫(xiě)下去的。加油各位!?。。。?!

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

          前言

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

          `解決思路:

          1.上傳word文件

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

          3.后臺(tái)讀取html文件內(nèi)容返回給前端


          一、目標(biāo)

          通過(guò)上傳word文件,通過(guò)后臺(tái)進(jìn)行解析回顯到前端。



          二、代碼步驟

          后端代碼結(jié)構(gòu):


          1.maven依賴(lài)庫(kù)

          <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頁(yè)面讀取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" +
          " /* 上傳圖片配置項(xiàng) */\n" +
          " \"imageActionName\": \"catcherImage\", /* 執(zhí)行上傳圖片的action名稱(chēng) */\n" +
          " \"imageFieldName\": \"upfile\", /* 提交的圖片表單名稱(chēng) */\n" +
          " \"imageMaxSize\": 2048, /* 上傳大小限制,單位B */\n" +
          " \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 上傳圖片格式顯示 */\n" +
          " \"imageCompressEnable\": true, /* 是否壓縮圖片,默認(rèn)是true */\n" +
          " \"imageCompressBorder\": 800, /* 圖片壓縮最長(zhǎng)邊限制 */\n" +
          " \"imageInsertAlign\": \"none\", /* 插入的圖片浮動(dòng)方式 */\n" +
          " \"imageUrlPrefix\": \"" + urlPrefix + "\", /* 圖片訪(fǎng)問(wèn)路徑前綴 */\n" +
          " \"imagePathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " /* {filename} 會(huì)替換成原文件名,配置這項(xiàng)需要注意中文亂碼問(wèn)題 */\n" +
          " /* {rand:6} 會(huì)替換成隨機(jī)數(shù),后面的數(shù)字是隨機(jī)數(shù)的位數(shù) */\n" +
          " /* {time} 會(huì)替換成時(shí)間戳 */\n" +
          " /* {yyyy} 會(huì)替換成四位年份 */\n" +
          " /* {yy} 會(huì)替換成兩位年份 */\n" +
          " /* {mm} 會(huì)替換成兩位月份 */\n" +
          " /* {dd} 會(huì)替換成兩位日期 */\n" +
          " /* {hh} 會(huì)替換成兩位小時(shí) */\n" +
          " /* {ii} 會(huì)替換成兩位分鐘 */\n" +
          " /* {ss} 會(huì)替換成兩位秒 */\n" +
          " /* 非法字符 \\ : * ? \" < > | */\n" +
          " /* 具請(qǐng)?bào)w看線(xiàn)上文檔: fex.baidu.com/ueditor/#use-format_upload_filename */\n" +
          "\n" +
          " /* 涂鴉圖片上傳配置項(xiàng) */\n" +
          " \"scrawlActionName\": \"uploadscrawl\", /* 執(zhí)行上傳涂鴉的action名稱(chēng) */\n" +
          " \"scrawlFieldName\": \"upfile\", /* 提交的圖片表單名稱(chēng) */\n" +
          " \"scrawlPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"scrawlMaxSize\": 2048000, /* 上傳大小限制,單位B */\n" +
          " \"scrawlUrlPrefix\": \"\", /* 圖片訪(fǎng)問(wèn)路徑前綴 */\n" +
          " \"scrawlInsertAlign\": \"none\",\n" +
          "\n" +
          " /* 截圖工具上傳 */\n" +
          " \"snapscreenActionName\": \"uploadimage\", /* 執(zhí)行上傳截圖的action名稱(chēng) */\n" +
          " \"snapscreenPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"snapscreenUrlPrefix\": \"\", /* 圖片訪(fǎng)問(wèn)路徑前綴 */\n" +
          " \"snapscreenInsertAlign\": \"none\", /* 插入的圖片浮動(dòng)方式 */\n" +
          "\n" +
          " /* 抓取遠(yuǎn)程圖片配置 */\n" +
          " \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n" +
          " \"catcherActionName\": \"catchimage\", /* 執(zhí)行抓取遠(yuǎn)程圖片的action名稱(chēng) */\n" +
          " \"catcherFieldName\": \"source\", /* 提交的圖片列表表單名稱(chēng) */\n" +
          " \"catcherPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"catcherUrlPrefix\": \"" + urlPrefix + "\", /* 圖片訪(fǎng)問(wèn)路徑前綴 */\n" +
          " \"catcherMaxSize\": 2048000, /* 上傳大小限制,單位B */\n" +
          " \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 抓取圖片格式顯示 */\n" +
          "\n" +
          " /* 上傳視頻配置 */\n" +
          " \"videoActionName\": \"uploadvideo\", /* 執(zhí)行上傳視頻的action名稱(chēng) */\n" +
          " \"videoFieldName\": \"upfile\", /* 提交的視頻表單名稱(chēng) */\n" +
          " \"videoPathFormat\": \"/ueditor/video/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"videoUrlPrefix\": \"\", /* 視頻訪(fǎng)問(wèn)路徑前綴 */\n" +
          " \"videoMaxSize\": 10240000, /* 上傳大小限制,單位B,默認(rèn)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名稱(chēng) */\n" +
          " \"fileFieldName\": \"upfile\", /* 提交的文件表單名稱(chēng) */\n" +
          " \"filePathFormat\": \"/ueditor/file/{yyyy}{mm}{dd}/\", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */\n" +
          " \"fileUrlPrefix\": \"\", /* 文件訪(fǎng)問(wèn)路徑前綴 */\n" +
          " \"fileMaxSize\": 10240000, /* 上傳大小限制,單位B,默認(rèn)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名稱(chēng) */\n" +
          " \"imageManagerListPath\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* 指定要列出圖片的目錄 */\n" +
          " \"imageManagerListSize\": 20, /* 每次列出文件數(shù)量 */\n" +
          " \"imageManagerUrlPrefix\": \"" + urlPrefix + "\", /* 圖片訪(fǎng)問(wèn)路徑前綴 */\n" +
          " \"imageManagerInsertAlign\": \"none\", /* 插入的圖片浮動(dòng)方式 */\n" +
          " \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 列出的文件類(lèi)型 */\n" +
          " /* 列出指定目錄下的文件 */\n" +
          " \"fileManagerActionName\": \"listfile\", /* 執(zhí)行文件管理的action名稱(chēng) */\n" +
          " \"fileManagerListPath\": \"/ueditor/file/{yyyy}{mm}{dd}/\", /* 指定要列出文件的目錄 */\n" +
          " \"fileManagerUrlPrefix\": \"\", /* 文件訪(fǎng)問(wèn)路徑前綴 */\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" +
          " ] /* 列出的文件類(lèi)型 */\n" +
          "}";
          PrintWriter writer=response.getWriter();
          writer.write(exec);
          writer.flush();
          writer.close();
          }

          ```

          3.前端導(dǎo)入文件

          代碼如下:

          methods: {
          ready(editorInstance) {
            this.editorInstance=editorInstance
            async uploadWordFile(event) {
            const file=event.target.files[0];
            if (!file) return;
            // 將Word文件轉(zhuǎn)換為HTML
            const htmlContent=await this.convertWordToHtml(file);
            const jsonData=JSON.parse(htmlContent)
            // 設(shè)置UEditor的內(nèi)容
            console.log(jsonData)
            this.editorInstance.execCommand('inserthtml',jsonData.data)
          },
          async convertWordToHtml(wordFile) {
            // 這里應(yīng)該是Word文件轉(zhuǎn)HTML的后端接口調(diào)用代碼
            // 假設(shè)有一個(gè)轉(zhuǎn)換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('轉(zhuǎn)換失敗');
          }
          }


          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工具類(lèi)

          ??????????

          options.URIResolver(new BasicURIResolver(picUri));

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

          ??????????

          代碼如下:
          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);
                  //獲取一個(gè)用操作Word的對(duì)象
                  XWPFDocument document=new XWPFDocument(file.getInputStream());
                  //導(dǎo)出為html時(shí)的一些基本設(shè)置類(lèi)
                  XHTMLOptions options=null;
                  //判斷word文件中是否有圖片
                  if(document.getAllPictures().size() > 0) {
                  //獲取默認(rèn)的對(duì)象,設(shè)置縮進(jìn)indent
                  options=XHTMLOptions.getDefault().indent(4);
                  // 如果包含圖片的話(huà),要設(shè)置圖片的導(dǎo)出位置
                  File imageFolder=new File(imagePath);
                  //設(shè)置圖片抽取器的目的地文件夾 用于存放圖片文件
                  options.setExtractor(new FileImageExtractor(imageFolder));
                  // URI resolver word的html中圖片的目錄路徑
                  //??????????????????????????????????
                  //?????????? 這里需要設(shè)置為前端能過(guò)直接訪(fǎng)問(wèn)到的圖片地址, 比如作者:http://localhost:8000/resource/ueditor/file/20240404/1712220732312.png,
                  //?????????? 否則,ueditor編輯器無(wú)法顯示word文檔中的圖片
                  String picUri=ueProperties.getShowpath().concat(imagePath.substring(imagePath.indexOf("ueditor")));
                  options.URIResolver(new BasicURIResolver(picUri));
                }
                //獲取輸出的html文件對(duì)象
                File outFile=new File(fileOutName);
                if(!outFile.getParentFile().exists()){
                outFile.getParentFile().mkdirs();
                }
                //創(chuàng)建所有的父路徑,如果不存在父目錄的話(huà)
                outFile.getParentFile().mkdirs();
                //創(chuàng)建一個(gè)輸出流
                OutputStream out=new FileOutputStream(outFile);
                //html轉(zhuǎn)換器
                XHTMLConverter.getInstance().convert(document, out, options);
                log.info("html轉(zhuǎn)換器 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ù)組流獲取解析的內(nèi)容
                ByteArrayOutputStream baos=new ByteArrayOutputStream();
                OutputStream outStream=new BufferedOutputStream(baos);
                try {
                String fileName=UUID.fastUUID().toString();
                //將上傳的文件傳入Document轉(zhuǎn)換
                //圖片存放地址
                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)建圖片文件的存儲(chǔ)目錄
                new File(imagePath).mkdirs();
                //poi中doc文檔對(duì)應(yīng)的實(shí)體類(lèi)
                HWPFDocument hwpfDocument=new HWPFDocument(file.getInputStream());
                //使用空的文檔對(duì)象構(gòu)建一個(gè)轉(zhuǎn)換對(duì)象
                WordToHtmlConverter converter=new WordToHtmlConverter(DocumentBuilderFactory
                .newInstance()
                .newDocumentBuilder()
                .newDocument());
                //設(shè)置存儲(chǔ)圖片的管理者--使用匿名內(nèi)部類(lèi)實(shí)現(xiàn) 該類(lèi)實(shí)現(xiàn)了PicturesManager接口,實(shí)現(xiàn)了其中的savePicture方法
                converter.setPicturesManager(new PicturesManager() {
                FileOutputStream out=null;
                //在下面的processDocument方法內(nèi)部會(huì)調(diào)用該方法 用于存儲(chǔ)word中的圖片文件
                @Override
                public String savePicture(byte[] bytes, PictureType pictureType, String name, float width, float height) {
                try {
                //單個(gè)照片的保存
                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)一個(gè)存儲(chǔ)的路徑 用于生成Html時(shí)定位到圖片資源
          //??????????????????????????????????
          //?????????? 這里需要設(shè)置為前端能過(guò)直接訪(fǎng)問(wèn)到的圖片地址, 比如作者:http://localhost:8000/resource/ueditor/file/20240404/1712220732312.png,
          //?????????? 否則,ueditor編輯器無(wú)法顯示word文檔中的圖片
          			return ueProperties.getShowpath().concat(imagePath.substring(imagePath.indexOf("ueditor"))).concat(name);
                }
                });
                //使用外觀模式,將hwpfDocument文檔對(duì)象設(shè)置給HtmlDocumentFacade中的Document屬性
                converter.processDocument(hwpfDocument);
                //獲取轉(zhuǎn)換器中的document文檔
                Document htmlDocument=converter.getDocument();
                //充當(dāng)文檔對(duì)象模型 (DOM) 樹(shù)形式的轉(zhuǎn)換源樹(shù)的持有者 -- 源樹(shù)
                DOMSource domSource=new DOMSource(htmlDocument);
                //轉(zhuǎn)換器 該對(duì)象用于將源樹(shù)轉(zhuǎn)換為結(jié)果樹(shù)
                Transformer transformer=TransformerFactory.newInstance().newTransformer();
                //設(shè)置輸出時(shí)的以什么方式輸出,也可說(shuō)是結(jié)果樹(shù)的文件類(lèi)型 可以是html/xml/text或者是一些擴(kuò)展前三者的擴(kuò)展類(lèi)型
                transformer.setOutputProperty(OutputKeys.METHOD , "html");
                //設(shè)置一些必要的屬性 設(shè)置輸出時(shí)候的編碼為utf-8
                transformer.setOutputProperty(OutputKeys.ENCODING , "utf-8");
                //轉(zhuǎn)換 將輸入的源樹(shù)轉(zhuǎn)換為結(jié)果樹(shù)并且輸出到streamResult中
                transformer.transform(domSource , new StreamResult(new File(fileOutName)));
                log.info("html轉(zhuǎn)換器 success");
                //處理生成的html,字符串形式給前端
                return readHtmlStr(fileOutName);
                } catch (Exception e) {
                log.error("docToHtmlText 異常", e);
                } finally {
                baos.close();
                outStream.close();
                }
                return null;
          }
          /**
          * 讀取html文件,轉(zhuǎn)成字符串返回給前端
          * 去除換行,以及連續(xù)兩個(gè)空格
          * @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,字符串形式出錯(cuò)了, {}", e.getMessage());
          }
          return htmlStr;
          }
          }


          6.后端配置文件

          代碼如下:

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


          三、實(shí)現(xiàn)效果

          成功通過(guò)導(dǎo)入word文章,回顯內(nèi)容到ueditor編輯器


          總結(jié)

          *贈(zèng)人玫瑰,手留余香*

          源碼地址:

          https://gitee.com/gwancookie/uedemo

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

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

          文本編輯器實(shí)現(xiàn)效果圖:

          關(guān)注,轉(zhuǎn)發(fā),私信小編“01”即可獲取Python入門(mén)學(xué)習(xí)資料!

          左側(cè)編輯區(qū)域,右側(cè)渲染到HTML顯示效果,除了渲染時(shí)候代碼樣式有所不同,其他標(biāo)題、文字、圖片基本滿(mǎn)足所見(jiàn)即所得的效果




          下面講解富文本編輯器在Django項(xiàng)目中如何使用

          1、前端頁(yè)面引入js文件:

          所用編輯器為tinymce.js,引入兩個(gè)js文件

          2、html代碼布局:

          左側(cè)編輯區(qū)域,右側(cè)渲染后預(yù)覽區(qū)域

          下面div左浮動(dòng),里面的textarea是富文本編輯區(qū)域,注意id要用rich_content,name也要加, {{ content }}是我在提交時(shí)候后端返回的數(shù)據(jù),方便重新在編輯區(qū)域渲染數(shù)據(jù)

          submit通過(guò)表單默認(rèn)的提交方式向后端發(fā)post請(qǐng)求傳數(shù)據(jù)

          下面是右側(cè)展示的div,右浮動(dòng),左右浮動(dòng)為了更好地對(duì)比效果,不用來(lái)回滑動(dòng)滾動(dòng)條,返回的content其實(shí)就是html字符串,我們渲染到瀏覽器即可

          3、Django后端代碼

          @csrf_exempt是ajax和form表單的post請(qǐng)求csrf解決辦法,如果是form表單的post請(qǐng)求,也可以在form中加{% csrf_token %}

          前端是form表單請(qǐng)求,后端只需要根據(jù)鍵從表單中讀數(shù)據(jù)就行,我們的富文本編輯器name屬性值為content,則直接get("content")即可

          返回到前端的content,即富文本的html字符串,我們分別在編輯器和右側(cè)都進(jìn)行了渲染,即可見(jiàn)到最開(kāi)始的效果

          本文富文本編輯器僅測(cè)試部分常見(jiàn)效果沒(méi)有什么問(wèn)題,另外富文本編輯器也有CKeditor、Ueditor等等,如果大佬們有關(guān)于這些的開(kāi)源demo,也歡迎學(xué)習(xí)交流


          主站蜘蛛池模板: 中文字幕一区二区视频| 国产日韩一区二区三区在线观看| 亚洲AV无码一区二区乱子仑| 国内精自品线一区91| 亚洲国产精品第一区二区| 亚洲成人一区二区| 国产品无码一区二区三区在线| 国产一区二区三区在线2021 | 久久婷婷色综合一区二区| 中文字幕av日韩精品一区二区| 国产探花在线精品一区二区 | 精品无码日韩一区二区三区不卡| 精品一区二区三区影院在线午夜| 欧洲精品码一区二区三区| 高清国产AV一区二区三区| 上原亚衣一区二区在线观看| 精品视频一区二区观看| 国内精品视频一区二区八戒| 日韩一区二区a片免费观看| 一本一道波多野结衣AV一区| 亚洲一区二区三区在线观看蜜桃| 无码人妻精品一区二区三区久久| 日本不卡免费新一区二区三区| 中文字幕在线观看一区| V一区无码内射国产| 一区二区乱子伦在线播放| 香蕉一区二区三区观| 免费萌白酱国产一区二区三区| 国产综合无码一区二区三区| 中文字幕色AV一区二区三区| 一区二区三区日本视频| 日本不卡一区二区三区视频| 久久国产精品最新一区| 亚欧色一区W666天堂| 精品一区二区视频在线观看| 亚洲色偷精品一区二区三区| 精品无码国产AV一区二区三区| 波多野结衣在线观看一区| 亚洲国产一区二区三区| 乱色精品无码一区二区国产盗| 亚洲乱码av中文一区二区|