Apache POI生成的pptx在office中打不开 兼容问题 wps中可以打卡问题 POI显示兼容问题

06-01 1295阅读

项目场景:

在java服务中使用了apache.poi后生成的pptx在wps中打开是没有问题,但在office中打开显示如下XXX内容问题,修复(R)等问题

我是用的依赖版本如下

    org.apache.poi
    poi
    5.2.3


    org.apache.poi
    poi-ooxml
    5.2.3


原因分析:

提示:可以把适配的解压看里面的slide,有部分格式是不同的,为此直接用下面的服务层即可,我使用的纯流方式,没有文件夹,输入输出都是可以让AI帮你修改下的,主流程逻辑不要动


解决方案:

package com.project.zcustom.service.converter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.*;
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.XPathFactory;
import java.io.*;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
@Slf4j
@Service
public class PptXmlFormateService {
    @Autowired
    private Executor threadPoolTaskExecutor;
    public byte[] xmlFormate(byte[] pptxBytes, String useFont) {
        useFont = StringUtils.isBlank(useFont) ? "宋体" : useFont;
        ByteArrayOutputStream resultStream = new ByteArrayOutputStream();
        try (ByteArrayInputStream bis = new ByteArrayInputStream(pptxBytes);
             ZipInputStream zis = new ZipInputStream(bis);
             ZipOutputStream zos = new ZipOutputStream(resultStream)) {
            Map updatedFiles = new HashMap();
            // 遍历PPTX文件中的每个条目
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                String entryName = entry.getName();
                ByteArrayOutputStream entryData = new ByteArrayOutputStream();
                // 读取条目内容
                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")) {
                    try (ByteArrayInputStream xmlBais = new ByteArrayInputStream(entryData.toByteArray());
                         ByteArrayOutputStream updatedXml = new ByteArrayOutputStream()) {
                        // 解析XML
                        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                        factory.setNamespaceAware(true);
                        DocumentBuilder builder = factory.newDocumentBuilder();
                        Document document = builder.parse(xmlBais);
                        // 异步任务处理XML
                        CompletableFuture future = CompletableFuture.runAsync(() -> {
                            // 删除标签
                            String custDataLstXpath = "//*[local-name()='custDataLst']";
                            removeNodesUsingXPath(document, custDataLstXpath);
                        }, threadPoolTaskExecutor);
                        // 等待任务完成并处理异常
                        future.exceptionally(ex -> {
                            log.error("处理XML异步任务时发生错误: {}", ex.getMessage(), ex);
                            return null;
                        }).join();
                        // 写入修改后的XML内容
                        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);
                    } catch (Exception e) {
                        log.error("处理XML文件时发生错误: {}", e.getMessage(), e);
                        // 发生错误时保留原文件内容
                        updatedFiles.put(entryName, entryData);
                    }
                } else {
                    // 对于其他条目,保持原样
                    updatedFiles.put(entryName, entryData);
                }
            }
            // 写入更新后的PPTX文件
            for (Map.Entry fileEntry : updatedFiles.entrySet()) {
                String entryName = fileEntry.getKey();
                ByteArrayOutputStream fileData = fileEntry.getValue();
                zos.putNextEntry(new ZipEntry(entryName));
                fileData.writeTo(zos);
                zos.closeEntry();
            }
        } catch (Exception e) {
            log.error("处理PPTX字节数组时发生错误: {}", e.getMessage(), e);
            throw new RuntimeException("PPTX处理失败", e);
        }
        return resultStream.toByteArray();
    }
    // 保持原有的XML节点移除方法不变
    public void removeNodesUsingXPath(Document document, String xpathExpression) {
        // 方法实现与原代码相同...
        XPath xPath = XPathFactory.newInstance().newXPath();
        // 设置命名空间前缀和 URI
        NamespaceContext 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());
        }
    }
}

这里换上你自己的项目的Executor或者默认的即可,调用xmlFormate方法即可

Apache POI生成的pptx在office中打不开 兼容问题 wps中可以打卡问题 POI显示兼容问题
(图片来源网络,侵删)
Apache POI生成的pptx在office中打不开 兼容问题 wps中可以打卡问题 POI显示兼容问题
(图片来源网络,侵删)
Apache POI生成的pptx在office中打不开 兼容问题 wps中可以打卡问题 POI显示兼容问题
(图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码