中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

小程序開(kāi)發(fā)費(fèi)用計(jì)入什么科目seo服務(wù)商技術(shù)好的公司

小程序開(kāi)發(fā)費(fèi)用計(jì)入什么科目,seo服務(wù)商技術(shù)好的公司,義安區(qū)住房和城鄉(xiāng)建設(shè)局建網(wǎng)站,美國(guó)中國(guó)日本韓國(guó)poi生成的ppt,powerPoint打開(kāi)提示內(nèi)容錯(cuò)誤解決方案 最近做了ppt的生成,使用poi制作ppt,出現(xiàn)一個(gè)問(wèn)題。微軟的powerPoint打不開(kāi),提示錯(cuò)誤信息 通過(guò)xml對(duì)比工具發(fā)現(xiàn)只需要?jiǎng)h除幻燈片的某些標(biāo)簽即可解決。 用的是XML Notepand 分…

poi生成的ppt,powerPoint打開(kāi)提示內(nèi)容錯(cuò)誤解決方案

最近做了ppt的生成,使用poi制作ppt,出現(xiàn)一個(gè)問(wèn)題。微軟的powerPoint打不開(kāi),提示錯(cuò)誤信息

在這里插入圖片描述

通過(guò)xml對(duì)比工具發(fā)現(xiàn)只需要?jiǎng)h除幻燈片的某些標(biāo)簽即可解決。

用的是XML Notepand
在這里插入圖片描述

分析思路:

1.把poi生成的pptx用wps打開(kāi),正常,但是poi生成的pptx在powerPoint打不開(kāi)。嘗試用wps另存一份,ok,wps另存后的ppt,powerPoint可以打開(kāi)了。然后ppt的大小也有了變化,肯定是wps對(duì)這個(gè)ppt做了一些格式化操作。具體是啥呢,不清楚,只能用這個(gè) XML Notepand 對(duì)比看看吧。
2. ppt本質(zhì)上是xml的壓縮包集合。我們對(duì)ppt進(jìn)行解壓。

在這里插入圖片描述

3.里面的東西挺多了,我自己也不怎么懂,但是我想既然是ppt的某個(gè)幻燈片打不開(kāi),那我就對(duì)比一下能幻燈片,看看poi生成的ppt和wps另存后的ppt的幻燈片有哪些區(qū)別。

我們進(jìn)入這個(gè)目錄
在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述

4.這個(gè)就是放置幻燈片的位置。

我們通過(guò)這個(gè)XML Notepand 進(jìn)行一個(gè)對(duì)比觀察,
在這里插入圖片描述
我們先用xml notePand打開(kāi)poi生成的一個(gè)幻燈片,我打開(kāi)的是wsp另存的解壓后的第4個(gè)幻燈片,ppt\slides\slide4.xml
在這里插入圖片描述

在這里插入圖片描述

然后選擇這個(gè),再次選擇一個(gè)poi生成的ppt,選擇同一個(gè)幻燈片,進(jìn)行一個(gè)對(duì)比
在這里插入圖片描述
然后進(jìn)行兩個(gè)文件對(duì)比
在這里插入圖片描述

最后對(duì)比發(fā)現(xiàn)這個(gè)標(biāo)簽可能不可以被powerPoint正確識(shí)別,我們就把這個(gè)標(biāo)簽刪除

在這里插入圖片描述

<p:custDataLst><p:tags r:id="rId1"/>
</p:custDataLst>

最關(guān)鍵的來(lái)了,直接上代碼

package com.ruoyi.ppt.utilsService;import com.ruoyi.ppt.aopCustom.customAnnotations.LogExecutionTime;
import com.ruoyi.ppt.config.ThreadPoolDealTask;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.w3c.dom.*;import javax.annotation.Resource;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
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 javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;@Slf4j
@Component
public class PptXmlFormate {@Resourceprivate ThreadPoolDealTask threadPoolDealTask;@LogExecutionTime("PPT XML標(biāo)簽調(diào)整耗時(shí)")public void xmlFormate(String pptxFilePath, String useFont) {useFont = StringUtils.isBlank(useFont) ? "宋體" : useFont;// 使用 try-with-resources 自動(dòng)關(guān)閉臨時(shí)文件和 Zip 流try {// 創(chuàng)建臨時(shí)文件來(lái)存儲(chǔ)更新后的 PPTX 文件File tempFile = File.createTempFile("pptx_temp" + UUID.randomUUID(), ".zip");tempFile.deleteOnExit();// 讀取 PPTX 文件并更新 XMLtry (FileInputStream fis = new FileInputStream(pptxFilePath);ZipInputStream zis = new ZipInputStream(fis);FileOutputStream fos = new FileOutputStream(tempFile);ZipOutputStream zos = new ZipOutputStream(fos)) {ZipEntry entry;Map<String, ByteArrayOutputStream> updatedFiles = new HashMap<>();// 遍歷 PPTX 文件中的每個(gè)條目while ((entry = zis.getNextEntry()) != null) {String entryName = entry.getName();ByteArrayOutputStream entryData = new ByteArrayOutputStream();// 讀取條目?jī)?nèi)容byte[] buffer = new byte[1024];int len;while ((len = zis.read(buffer)) > 0) {entryData.write(buffer, 0, len);}// 僅處理幻燈片 XML 文件if (entryName.startsWith("ppt/slides/slide") && entryName.endsWith(".xml")) {// 解析 XMLtry (ByteArrayInputStream bais = new ByteArrayInputStream(entryData.toByteArray());ByteArrayOutputStream updatedXml = new ByteArrayOutputStream()) {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();factory.setNamespaceAware(true);DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse(bais);// 異步任務(wù),并確保異常捕獲CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {// 刪除標(biāo)簽String custDataLstXpath = "//*[local-name()='custDataLst']";removeNodesUsingXPath(document, custDataLstXpath);}, threadPoolDealTask.getThreadPoolExecutor());// 捕獲并處理異步任務(wù)中的異常future.exceptionally(ex -> {log.error("處理 XML 異步任務(wù)時(shí)發(fā)生錯(cuò)誤: {}", ex.getMessage(), ex);return null;}).join(); // 等待任務(wù)完成// 寫(xiě)入修改后的 XML 內(nèi)容TransformerFactory transformerFactory = TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();transformer.setOutputProperty(OutputKeys.INDENT, "yes");DOMSource source = new DOMSource(document);StreamResult result = new StreamResult(updatedXml);transformer.transform(source, result);updatedFiles.put(entryName, updatedXml);}} else {// 對(duì)于其他條目,保持原樣updatedFiles.put(entryName, entryData);}}// 寫(xiě)入更新后的 PPTX 文件for (Map.Entry<String, ByteArrayOutputStream> fileEntry : updatedFiles.entrySet()) {String entryName = fileEntry.getKey();ByteArrayOutputStream fileData = fileEntry.getValue();zos.putNextEntry(new ZipEntry(entryName));fileData.writeTo(zos);zos.closeEntry();}zos.finish();}// 將臨時(shí)文件移動(dòng)到原始 PPTX 文件路徑,替換原文件Files.move(tempFile.toPath(), new File(pptxFilePath).toPath(), StandardCopyOption.REPLACE_EXISTING);} catch (IOException e) {log.error("處理文件時(shí)發(fā)生 IO 錯(cuò)誤: {}", e.getMessage(), e);} catch (Exception e) {log.error("處理過(guò)程中發(fā)生錯(cuò)誤: {}", e.getMessage(), e);}}public void removeNodesUsingXPath(Document document, String xpathExpression) {XPath xPath = XPathFactory.newInstance().newXPath();// 設(shè)置命名空間前綴和 URINamespaceContext nsContext = new NamespaceContext() {public String getNamespaceURI(String prefix) {switch (prefix) {case "a":return "http://schemas.openxmlformats.org/drawingml/2006/main";case "p":return "http://schemas.openxmlformats.org/presentationml/2006/main";default:return XMLConstants.NULL_NS_URI;}}public String getPrefix(String namespaceURI) {return null;}public Iterator getPrefixes(String namespaceURI) {return null;}};xPath.setNamespaceContext(nsContext);try {NodeList nodes = (NodeList) xPath.evaluate(xpathExpression, document, XPathConstants.NODESET);for (int i = nodes.getLength() - 1; i >= 0; i--) { // 從后向前遍歷Node node = nodes.item(i);Node parentNode = node.getParentNode();if (parentNode != null) {parentNode.removeChild(node);}}} catch (Exception e) {log.error("Error removing nodes using XPath: {}", e.getMessage());}}}

注意哈,這里使用了線程池,不需要的可以刪除,需要的話不會(huì)配置的,這里也給出代碼

package com.ruoyi.ppt.config;import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;import javax.annotation.Resource;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;@Slf4j
@Configuration
@Data
public class ThreadPoolDealTask {private volatile ThreadPoolExecutor threadPool;// 自定義 ThreadFactory,為線程池中的線程指定名稱private ThreadFactory createThreadFactory(String poolName) {AtomicInteger counter = new AtomicInteger(0);return r -> {Thread thread = new Thread(r);thread.setName(poolName + "-thread-" + counter.incrementAndGet());return thread;};}// 懶加載線程池,只有在第一次使用時(shí)才會(huì)創(chuàng)建 用于 業(yè)務(wù)處理public void initializeThreadPool() {if (this.threadPool == null) {synchronized (this) {if (this.threadPool == null) { // 雙重檢查鎖定this.threadPool = new ThreadPoolExecutor(2,10,30L,TimeUnit.SECONDS,new LinkedBlockingQueue<>(50),createThreadFactory("CustomThreadPool"), // 使用自定義的 ThreadFactorynew ThreadPoolExecutor.CallerRunsPolicy());// 啟用核心線程超時(shí)this.threadPool.allowCoreThreadTimeOut(false);}}}}public ThreadPoolExecutor getThreadPoolExecutor() {return this.threadPool;}// 輸出任務(wù)隊(duì)列狀態(tài)private void printQueueStatus() {if (threadPool instanceof ThreadPoolExecutor) {ThreadPoolExecutor executor = (ThreadPoolExecutor) threadPool;System.out.println("Submitting task to thread: " + Thread.currentThread().getName());System.out.println("當(dāng)前任務(wù)隊(duì)列大小: " + executor.getQueue().size());System.out.println("當(dāng)前任務(wù)隊(duì)列大小: " + executor.getQueue().size());System.out.println("當(dāng)前活動(dòng)線程數(shù): " + executor.getActiveCount());System.out.println("當(dāng)前線程池大小: " + executor.getPoolSize());}}// 提交任務(wù)并返回Future對(duì)象public <T> Future<T> submitTask(Callable<T> task) {initializeThreadPool(); // 確保線程池已初始化return threadPool.submit(task);}// 提交Runnable任務(wù)并返回Futurepublic Future<?> submitTask(Runnable task) {initializeThreadPool(); // 確保線程池已初始化return threadPool.submit(task);}// 優(yōu)雅地關(guān)閉線程池public void shutdown() {if (threadPool != null) {threadPool.shutdown();try {// 等待現(xiàn)有任務(wù)執(zhí)行完畢if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {threadPool.shutdownNow(); // 強(qiáng)制關(guān)閉// 等待任務(wù)響應(yīng)中斷if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {System.err.println("線程池未能在指定時(shí)間內(nèi)關(guān)閉");}}} catch (InterruptedException ie) {// 在當(dāng)前線程被中斷時(shí),也強(qiáng)制關(guān)閉線程池threadPool.shutdownNow();// 保留中斷狀態(tài)Thread.currentThread().interrupt();} finally {threadPool = null; // 關(guān)閉后將線程池引用置為空}}}}

現(xiàn)在解決了xml的標(biāo)簽問(wèn)題,

最后只需要生成后的ppt地址,傳入這個(gè)方法,執(zhí)行一次標(biāo)簽刪除即可

處理前效果:
在這里插入圖片描述

處理后效果:
在這里插入圖片描述

http://www.risenshineclean.com/news/51512.html

相關(guān)文章:

  • 安康網(wǎng)站建設(shè)公司最新推廣注冊(cè)app拿傭金
  • 保健品網(wǎng)站設(shè)計(jì)短視頻營(yíng)銷案例
  • 做戒指網(wǎng)站的logo照片想做個(gè)網(wǎng)絡(luò)推廣
  • 深圳做網(wǎng)站公司 南山廊坊百度推廣電話
  • 淘寶客網(wǎng)站備案信息百度指數(shù)有什么作用
  • 網(wǎng)站怎么做跳轉(zhuǎn)鏈接最近新聞今日頭條
  • 什么網(wǎng)站可以查建筑工程項(xiàng)目怎么在百度上發(fā)布信息廣告
  • 好用的代碼網(wǎng)站百度推廣優(yōu)化師是什么
  • 東莞常平二手房?jī)r(jià)最新消息重慶seo1
  • 網(wǎng)站手機(jī)版怎么做百度明星人氣榜入口
  • 教育培訓(xùn)有限公司可以多少錢注冊(cè)seo怎么優(yōu)化效果更好
  • 江西哪里有做電商網(wǎng)站的公司地推推廣方案
  • 教你做網(wǎng)站廣州網(wǎng)絡(luò)科技有限公司
  • 什么網(wǎng)站可以自學(xué)ps做貴賓卡廣告推廣免費(fèi)
  • 西安建設(shè)工程信息平臺(tái)網(wǎng)絡(luò)優(yōu)化工程師為什么都說(shuō)坑人
  • 運(yùn)營(yíng)說(shuō)白了是什么意思珠海百度關(guān)鍵字優(yōu)化
  • 醫(yī)療器械做網(wǎng)站備案創(chuàng)建網(wǎng)站需要多少資金
  • 中國(guó)建設(shè)銀行官方網(wǎng)站首頁(yè)全網(wǎng)推廣的方式有哪些
  • 用美圖秀秀做網(wǎng)站圖片軟文營(yíng)銷的定義
  • 如何做單網(wǎng)頁(yè)網(wǎng)站抖音seo優(yōu)化公司
  • wordpress頁(yè)面自由布局神馬搜索seo優(yōu)化排名
  • 縣政府門(mén)戶網(wǎng)站建設(shè)方案品牌營(yíng)銷公司
  • 企業(yè)網(wǎng)站的基本內(nèi)容騰訊第三季度營(yíng)收448億元
  • 做網(wǎng)站賣廣告掙幾百萬(wàn)建站模板平臺(tái)
  • 南昌新建網(wǎng)站建設(shè)南京網(wǎng)絡(luò)推廣公司排名
  • 網(wǎng)站建設(shè)小組搜索引擎優(yōu)化方式
  • 網(wǎng)站開(kāi)發(fā)包含哪些網(wǎng)站下載
  • 免費(fèi)建站網(wǎng)站一級(jí)大陸在線看網(wǎng)站優(yōu)化推廣培訓(xùn)
  • 鞍山市住房和城鄉(xiāng)建設(shè)網(wǎng)站中國(guó)有幾個(gè)搜索引擎
  • 最優(yōu)的錦州網(wǎng)站建設(shè)專門(mén)搜索知乎內(nèi)容的搜索引擎