简体   繁体   English

使用OpenXML创建PowerPoint演示文稿时PPTX文件损坏

[英]Corrupted PPTX file when using OpenXML to create PowerPoint presentation

**Important: question answered after code block** **重要提示:代码块后回答的问题**

Platform: C#, OpenXML SDK (2.5), .NET 4.0 平台: C#,OpenXML SDK(2.5)、. NET 4.0

What I'm trying to achieve 我正在努力实现的目标

I've been trying to generate a pptx presentation from some data and images coming from my database. 我一直在尝试根据来自数据库的一些数据和图像生成一个pptx演示文稿。 Any generated file gets corrupted, but it's really passing the OOXML validation. 任何生成的文件均已损坏,但实际上已通过OOXML验证。 I really don't know what else I could do. 我真的不知道还能做什么。

What I've already tried 我已经尝试过的

I tried to remove the images, the text, then I've commented the code that deletes the first (template) slide but nothing changes my final result: a corrupted file. 我尝试删除图像,文本,然后注释了删除第一张(模板)幻灯片的代码,但没有改变我的最终结果:文件损坏。

The error 错误

When I try to open the file: "PowerPoint was unable to display some of the text, images, or objects on slides in the file, "filename.pptx", because they have become corrupted. Affected slides have been replaced by blank slides in the presentation and it is not possible to recover the lost information. To ensure that the file can be opened in previous versions of PowerPoint, use the Save As command (File menu) and save the file with either the same or a new name. 当我尝试打开文件时:“ PowerPoint无法显示文件幻灯片中的某些文本,图像或对象” filename.pptx”,因为它们已损坏。受影响的幻灯片已替换为空白幻灯片。为了确保可以在早期版本的PowerPoint中打开文件,请使用“另存为”命令(“文件”菜单)并使用相同或新名称保存文件。

Code

Here's the code I'm using to generate the PPTX: 这是我用来生成PPTX的代码:

void GenerateSlides(string fullPath, string path, IEnumerable<Data> data)
    {
        var slidePath = fullPath;

        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);

        // Copy the template file to generate new slides
        File.Copy(string.Format("{0}{1}", path, "TemplateTF.pptx"), slidePath, true);

        using (var presentationDocument = PresentationDocument.Open(slidePath, true))
        {
            var presentationPart = presentationDocument.PresentationPart;
            var slideTemplate = (SlidePart)presentationPart.GetPartById("rId2");

            // Recover the data to fullfill the slidepart
            int i = 1;

            foreach (var singleData in data)
            {
                (...)

                // Creates the new image
                var newSlide = CloneSlidePart(presentationPart, slideTemplate);
                var imgId = "rIdImg" + i;
                var imagePart = newSlide.AddImagePart(ImagePartType.Jpeg, imgId);
                var stream = new MemoryStream();
                using (var file = File.Open(string.Format("{0}{1}"
                    , WebConfigurationManager.AppSettings["pathImages"]
                    , singleData.ImageName), FileMode.Open))
                {
                    var buffer = new byte[file.Length];
                    file.Read(buffer, 0, (int)file.Length);
                    stream.Write(buffer, 0, buffer.Length);
                    imagePart.FeedData(new MemoryStream(buffer));
                }
                // Important method to swap the original image
                SwapPhoto(newSlide, imgId);
                i++;

                InsertContent(newSlide, (...));
                SwapPhoto(newSlide, imgId);
                newSlide.Slide.Save();
            }

            DeleteTemplateSlide(presentationPart, slideTemplate);
            presentationPart.Presentation.Save();
        }
    }

void SwapPhoto(SlidePart slidePart, string imgId)
    {
        var blip = slidePart.Slide.Descendants<Drawing.Blip>().First();
        blip.Embed = imgId;
        slidePart.Slide.Save();
    }

void DeleteTemplateSlide(PresentationPart presentationPart, SlidePart slideTemplate)
    {
        var slideIdList = presentationPart.Presentation.SlideIdList;
        foreach (SlideId slideId in slideIdList.ChildElements)
        {
            if (slideId.RelationshipId.Value.Equals("rId2"))
            {
                slideIdList.RemoveChild(slideId);
            }
        }
        presentationPart.DeletePart(slideTemplate);
    }

SlidePart CloneSlidePart(PresentationPart presentationPart, SlidePart slideTemplate)
    {
        var newSlidePart = presentationPart.AddNewPart<SlidePart>("newSlide" + i);
        i++;
        newSlidePart.FeedData(slideTemplate.GetStream(FileMode.Open));
        newSlidePart.AddPart(slideTemplate.SlideLayoutPart);

        var slideIdList = presentationPart.Presentation.SlideIdList;

        uint maxSlideId = 1;
        SlideId prevSlideId = null;
        foreach (SlideId slideId in slideIdList.ChildElements)
        {
            if (slideId.Id > maxSlideId)
            {
                maxSlideId = slideId.Id;
                prevSlideId = slideId;
            }
        }
        maxSlideId++;

        var newSlideId = slideIdList.InsertAfter(new SlideId(), prevSlideId);
        newSlideId.Id = maxSlideId;
        newSlideId.RelationshipId = presentationPart.GetIdOfPart(newSlidePart);

        return newSlidePart;
    }

void InsertContent(SlidePart slidePart, (...))
    {
        SwapPlaceholderText(slidePart, "Title", "ReplacementString1");
        SwapPlaceholderText(slidePart, "Text", "ReplacementString2");
    }

    void SwapPlaceholderText(SlidePart slidePart, string placeholder, string value)
    {
        var textList = slidePart.Slide.Descendants<Drawing.Text>().Where(
           t => t.Text.Equals(placeholder)).ToList();

        foreach (Drawing.Text text in textList)
        {
            text.Text = value;
        }
    }



Answer 回答

Ok, I realized how different MS Office versions can be. 好的,我意识到可以使用不同的MS Office版本。

a) If I try to open the .pptx file with Office 2013: error message + opens perfectly, no logo image nor slidepart showing any aditional information a)如果我尝试使用Office 2013打开.pptx文件:错误消息+完美打开,则徽标图像或幻灯片均未显示任何附加信息

b) If I try to open the .pptx file with Office 2007: error message + empty slides, no information at all b)如果我尝试使用Office 2007打开.pptx文件:错误消息+空幻灯片,则完全没有信息

c) If I try to open the .pptx file with Office 2010: error message + empty slides and the most important information I could ever have: corrupted icon in logo's place!!! c)如果我尝试使用Office 2010打开.pptx文件:错误消息+空幻灯片以及我可能拥有的最重要的信息:徽标位置的图标损坏!!!

I removed the logo image from my template and voilà, the file is is perfectly generated. 我从模板和voilà中删除了徽标图像,该文件已完美生成。 Now, if I really NEED to add the logo image, I can do it programatically. 现在,如果我真的需要添加徽标图像,则可以通过编程方式进行。

Thanks! 谢谢! After one week trying to realize what the hell was happening, a great friend of mine opened the file using Office 2010, then I DID realize the logo image was corrupted in my original template file. 经过一周的尝试来了解到底发生了什么之后,我的一个好朋友使用Office 2010打开了文件,然后我才意识到徽标图像在我的原始模板文件中已损坏。

Thanks :) 谢谢 :)

Ok, I realized how different MS Office versions can be. 好的,我意识到可以使用不同的MS Office版本。

a) If I try to open the .pptx file with Office 2013: error message + opens perfectly, no logo image nor slidepart showing any aditional information b) If I try to open the .pptx file with Office 2007: error message + empty slides, no information at all c) If I try to open the .pptx file with Office 2010: error message + empty slides and the most important information I could ever have: corrupted icon in logo's place!!! a)如果我尝试使用Office 2013打开.pptx文件:错误消息+完美打开,则没有徽标图像或Slidepart显示任何附加信息b)如果我尝试使用Office 2007打开.pptx文件:错误消息+空幻灯片,完全没有信息c)如果我尝试使用Office 2010打开.pptx文件:错误消息+空幻灯片以及我可能拥有的最重要信息:徽标位置的图标损坏!!!

I removed the logo image from my template and voilà, the file is is perfectly generated. 我从模板和voilà中删除了徽标图像,该文件已完美生成。 Now, if I really NEED to add the logo image, I can do it programatically. 现在,如果我真的需要添加徽标图像,则可以通过编程方式进行。

Thanks! 谢谢! After one week trying to realize what the hell was happening, a friend of mine opened the file using Office 2010, then I DID realize the logo image was corrupted in my original template file. 一个星期试图弄清楚到底是怎么回事后,我的一个朋友使用Office 2010打开了文件,然后我才意识到徽标图像在我的原始模板文件中已损坏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 OpenXML 从 Powerpoint 演示文稿中删除所有动画 pptx SDK - Remove all animations pptx from Powerpoint Presentation using OpenXML SDK 使用 openxml C# 生成的损坏的 powerpoint pptx - Corrupted powerpoint pptx generated using openxml C# 使用openXML创建模板演示文稿“.potx”的副本到新的“.pptx” - create a copy of template presentation “.potx” to a new “.pptx” using openXML 在Powerpoint中使用OpenXML创建表 - Create table using OpenXML in powerpoint 如何使用 c# 和 OpenXML 在 PowerPoint 演示文稿中调整大小和图像 - How to resize and image in a PowerPoint presentation using c# and OpenXML 如何使用OpenXml在.pptx文件的末尾添加新的空白幻灯片? - How to add new - blank slide at the end of .pptx file using OpenXml? 使用 OpenXML SDK 从 Powerpoint 演示文稿的主幻灯片中删除所有未使用的幻灯片布局 - Remove all unused Slide Layout from my Master Slide from Powerpoint Presentation using OpenXML SDK 如何在OpenXML / PresentationML / C#中的PowerPoint(PPTX)中插入换行符 - How to insert a newline in PowerPoint (PPTX) in OpenXML / PresentationML / C# 计算OpenXML(PresentationML)PowerPoint(PPTX)中文本(TextBody)的大小(范围) - Calculate the size (Extents) of a text (TextBody) in OpenXML (PresentationML) PowerPoint (PPTX) 以编程方式更改/添加pptx powerpoint的缩略图。 使用Openxml SDK? - Programmatically change/add thumbnail of pptx powerpoint. With Openxml sdk?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM