1

**重要: コード ブロックの後に回答された質問**

プラットフォーム: C#、OpenXML SDK (2.5)、.NET 4.0

私が達成しようとしていること

データベースから取得したデータと画像から pptx プレゼンテーションを生成しようとしています。生成されたファイルはすべて破損しますが、実際には OOXML 検証に合格しています。他に何ができるか本当にわかりません。

私がすでに試したこと

画像とテキストを削除しようとしましたが、最初の (テンプレート) スライドを削除するコードにコメントしましたが、最終結果は何も変わりません: 破損したファイルです。

エラー

ファイルを開こうとすると、「PowerPoint は、ファイル "filename.pptx" 内のスライドのテキスト、画像、またはオブジェクトの一部を表示できませんでした。それらが壊れているためです。失われた情報を復元することはできません。以前のバージョンの PowerPoint でファイルを開くことができるようにするには、[名前を付けて保存] コマンド ([ファイル] メニュー) を使用して、同じ名前または新しい名前でファイルを保存してください。

コード

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;
        }
    }



答え

わかりました、MS Office のバージョンが異なる可能性があることに気付きました。

a) Office 2013 で .pptx ファイルを開こうとすると: エラー メッセージ + 完全に開く

b) Office 2007 で .pptx ファイルを開こうとすると: エラー メッセージ + 空のスライド、情報がまったくない

c) Office 2010 で .pptx ファイルを開こうとすると: エラー メッセージ + 空のスライドと、最も重要な情報: ロゴの場所に破損したアイコン!!!

テンプレートからロゴ画像を削除したところ、ファイルが完全に生成されました。ロゴ画像を本当に追加する必要がある場合は、プログラムで行うことができます。

ありがとう!何が起こっているのかを理解するのに 1 週​​間費やした後、私の親友が Office 2010 を使用してファイルを開いたところ、元のテンプレート ファイルのロゴ画像が破損していることに気付きました。

ありがとう :)

4

1 に答える 1

2

わかりました、MS Office のバージョンが異なる可能性があることに気付きました。

a) Office 2013 で .pptx ファイルを開こうとすると: エラー メッセージ + 完全に開きます。追加情報を示すロゴ画像もスライド パーツもありません b) Office 2007 で .pptx ファイルを開こうとすると: エラー メッセージ + 空のスライド、情報がまったくありません c) Office 2010 で .pptx ファイルを開こうとすると、エラー メッセージ + 空のスライドと、これまでに得られた最も重要な情報: ロゴの場所に破損したアイコン!!!

テンプレートからロゴ画像を削除したところ、ファイルが完全に生成されました。ロゴ画像を本当に追加する必要がある場合は、プログラムで行うことができます。

ありがとう!何が起こっているのかを理解するのに 1 週​​間費やした後、私の友人が Office 2010 を使用してファイルを開いたところ、元のテンプレート ファイルのロゴ イメージが破損していることに気付きました。

于 2013-04-04T17:17:02.940 に答える