使用pageoffice的坑

本文详细探讨了解决从PageOffice编辑的Word文档中读取内容时出现乱码的方法,通过调整编码格式及使用POI库的不同组件(HWPFDocument与XWPFDocument)来适应WPS与Office的不同版本,确保跨软件兼容性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

               我需要读取pageoffice编辑保存后的文档内容,但是我们新建的word文件大多数都是iso88591格式的,所以读出后都是乱码,用了各种解码编码都不行,pageoffice生成的.htm文件本身是gb2312格式的,所以我用gb2312格式读出再转utf-8格式后没有出现乱码
               
               具体核心代码如下
               
     File fi=new File(htmlPath);
        if(fi.exists()) {
            try {
             ByteArrayOutputStream outHtml = new ByteArrayOutputStream(); 
             InputStream inn = new FileInputStream(fi);
             byte[] buffer = new byte[4096];  
             int len = 0;
             while((len = inn .read(buffer))!= -1 ){
                outHtml.write(buffer,0,len);
             }
             byte[] data = outHtml.toByteArray();
             htm=new String(data,"gb2312");
             htm=gb2312ToUtf8(htm);
             htm=htm.replaceAll(FileName,allcommonimagePath);
            }catch(IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        
        
        // 将 GB2312 编码格式的字符串转换为 UTF-8 格式的字符串:

public static String gb2312ToUtf8(String str) {

        String urlEncode = "" ;

        try {
            urlEncode = URLEncoder.encode (str, "UTF-8" );

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }
        
        return urlEncode;

}


但是对于生成的word文件怎么试都不行,读出都是乱码,我使用文件流写入另外一个文件也没乱码问题啊,后来发现因为两个文件编码格式都是iso88591,所以正常,

后来看资料说poi方式可以正常读出,试了一下果然可以,喜出望外,不料又带来了新的问题,poi的方式在不同电脑上会表现出不一样的,我的word编辑器是wps,使用如下方式读出文件内容(jar包自己网上找,我记得我用的是3.16,但是有个高版本的确没有,这里也被坑)
            FileInputStream fis = new FileInputStream(file);
                        HWPFDocument cx = new HWPFDocument(fis);
                        txtContent=cx.getDocumentText();

但是到了同事电脑(office)上却没有反应,查看日志报错了,错误the supplied data appears to be in the office 2007+xml,you are calling the part of POI that with OLE2 office Document .you need to call a different part of POI to process this data(eq XSSF of HSSF)
大致意思就是我需要调用不同的POI去处理不同的文档,网上看了一下XSSF表示2007+(2007之后的excel),HSSF支持2007-(2007之前的),
等效猜想word在HWPFD和XWPFD也是类似的特性,网上查了一下HWPF 是 POI 支持 Word(97-2003) 的 Java 组件,支持读写Word文档,但是写功能目前只实现一部分,XWPF是 POI 支持 Word 2007+ 的 Java组件
而我使用的的wps,我就郁闷了,于是查了一下wps和office的区别,wps兼容office,office不兼容wps,国产委屈脸。。
查看了一下解压安装包,发现我的wps外层文件夹是office6,也就解释通了我用了office6可以同事的office2007不行。
可能使用HWPFD和XWPFD对于wps和office来说就像excel对应XSSF和HSSF一样的特性,我试了wps的两个版本,office6和office7用XWPF都不行,但是用HWPDF确可以,office2007和office2013用XWPDF可以。
所以为了让用户都能读到数据,无论安装office还是wps,我就用了如下的写法:
File file=new File(pgFilePath);//创建一个新的file实例
        if(file.exists()){
            FileInputStream fis = new FileInputStream(file);
            logger.debug("读取内容前");
            XWPFDocument doc=null;
            try {
                OPCPackage po=OPCPackage.open(fis);
                doc = new XWPFDocument(po);
            } catch (InvalidFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                if(doc!=null){
                    XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
                    txtContent = extractor.getText();
                    extractor.close();
                    }else{
                        HWPFDocument cx = new HWPFDocument(fis);
                        txtContent=cx.getDocumentText();
                        cx.close();
                        fis.close();
                    }
                  return txtContent;
            }
        }else{
            return txtContent;
        }
        
以为问题解决了,但是一直出现
org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document
,郁闷,单独用XWPDF或者HWPFD都行,这样一起为什么不行
弄了好久没弄好,然后看到这里
https://stackoverflow.com/questions/33879515/notole2fileexception-invalid-header-signature-read-0x0000000000000000-expecte
So that explains why I get this error the next time I run the program and try to write the workbook on the same Excel file.
猛然悟出原来是自己习惯问题,文件流这里一直强调使用完需要关闭,我第一次    OPCPackage po=OPCPackage.open(fis);使用了FileInputStream,但是没有关闭,因为我的是wps,所以会走else,但是上一次的额fileinputstream并没有关闭,就直接想接着使用第二次,
两个连接用到inputstream,所以出现了该错误,改成如下后问题解决,不管if还是else都保证了文件字节流关闭,问题解决。


File file=new File(pgFilePath);//创建一个新的file实例
        if(file.exists()){
            FileInputStream fis = new FileInputStream(file);
            logger.debug("读取内容前");
            XWPFDocument doc=null;
            try {
                OPCPackage po=OPCPackage.open(fis);
                doc = new XWPFDocument(po);
            } catch (InvalidFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                if(doc!=null){
                    XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
                    txtContent = extractor.getText();
                    extractor.close();
                    fis.close();
                    }else{
                        fis.close();
                        fis = new FileInputStream(file);
                        HWPFDocument cx = new HWPFDocument(fis);
                        txtContent=cx.getDocumentText();
                        cx.close();
                        fis.close();
                    }
                  return txtContent;
            }
        }else{
            return txtContent;
        }

<think>嗯,用户问的是C# OpenXML是否支持操作Visio文件。这个问题看起来简单,但背后可能涉及用户正在处理Office文档自动化需求,特别是Visio相关的功能集成。 用户可能是个C#开发者,正在开发需要处理Office文档的应用程序。考虑到Visio在流程图、架构图方面的专业性,用户很可能需要批量生成或修改这类图表。不过用户似乎对OpenXML的适用范围不太清楚,需要明确边界。 从技术角度看,OpenXML SDK确实不支持Visio,这个要明确告知用户。但直接说"不支持"可能让用户失望,所以得提供替代方案。我想到几个关键点: 1)Visio有自己的二进制格式(vsdx)和XML结构,与Word/Excel的OpenXML不兼容 2)微软官方提供了Visio的互操作程序库 3)还有第三方库Aspose.Diagram这个选项 用户可能更关心实际解决方案而非技术细节,所以回复要侧重可操作方案。特别要注意提醒用户Visio互操作的部署问题——这个很多开发者都会踩到。另外Aspose虽然是商业库,但对需要深度集成Visio的用户来说值得考虑。 最后生成的问题要引导用户明确具体需求:到底是文件转换、内容提取还是图表生成?不同场景解决方案差异很大。比如如果只需要读取数据,解析XML可能就够用;若要动态生成图表,就得推荐完整SDK了。</think>关于C# OpenXML是否支持操作Visio文件,结论如下: ### 直接回答 **❌ OpenXML SDK 不支持直接操作 Visio 文件**。原因如下: 1. **格式差异** Visio 文件(`.vsdx`)虽然基于XML打包结构(Open Packaging Conventions),但使用的是 **Visio 专属的ML标记语言**(DrawingML的子集),而非OpenXML SDK主要支持的WordprocessingML/SpreadsheetML/PresentationML[^3]。 2. **SDK范围限制** OpenXML SDK的官方类库仅包含对Word、Excel、PPT的封装(如`DocumentFormat.OpenXml.Wordprocessing`),未提供对Visio元素的原生支持类[^3]。 --- ### 替代解决方案 #### 方案1:使用Visio互操作程序集(需安装Visio) ```csharp using Visio = Microsoft.Office.Interop.Visio; // 创建Visio应用实例 var app = new Visio.Application(); var doc = app.Documents.Open("diagram.vsdx"); // 操作示例:获取第一页 Visio.Page page = doc.Pages[1]; // 添加形状 var rectShape = page.DrawRectangle(1, 1, 4, 3); rectShape.Text = "示例文本"; doc.Save(); doc.Close(); app.Quit(); ``` > ⚠️ 需引用`Microsoft.Office.Interop.Visio`,且客户端必须安装Visio #### 方案2:第三方库(推荐) - **Aspose.Diagram for .NET** 商业库,提供完整API: ```csharp Diagram diagram = new Diagram("input.vsdx"); diagram.Pages[0].AddShape(2.0, 2.0, 3.0, 3.0, "Rectangle"); diagram.Save("output.vsdx", SaveFileFormat.VSDX); ``` - **NetOffice**(免费替代) 简化Interop调用: ```csharp using var app = new NetOffice.VisioApi.Application(); var doc = app.Documents.Open("diagram.vsdx"); doc.Pages[1].DrawRectangle(1, 1, 4, 3); ``` #### 方案3:手动解析ZIP包(仅基础操作) ```csharp using (var zip = ZipFile.Open("diagram.vsdx", ZipArchiveMode.Update)) { // 修改文档核心XML var coreEntry = zip.GetEntry("docProps/core.xml"); using (var stream = coreEntry.Open()) { XDocument doc = XDocument.Load(stream); var title = doc.Descendants("dc:title").FirstOrDefault(); title?.SetValue("新标题"); } } ``` > 需自行研究Visio XML结构,风险较高 --- ### 关键区别总结 | 文件类型 | OpenXML SDK支持 | 操作方式 | |----------------|-----------------|----------------------------| | Word(.docx) | ✅ 原生支持 | `WordprocessingDocument` | | Excel(.xlsx) | ✅ 原生支持 | `SpreadsheetDocument` | | PowerPoint(.pptx)| ✅ 原生支持 | `PresentationDocument` | | **Visio(.vsdx)**| ❌ **不支持** | 需Interop/第三方库 | ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值