**重要提示:之後的代碼塊回答過的問題**損壞的PPTX文件使用的OpenXML創建PowerPoint演示文稿時
平臺: 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版本如何不同都可以。
一)如果我嘗試打開與Office 2013的.pptx文件:錯誤信息+打開完美,沒有任何標識形象,也不是slidepart顯示任何aditional的信息
B)如果我嘗試打開.PPTX文件與Office 2007:錯誤消息+空幻燈片,在所有
C無信息)如果我嘗試打開與Office 2010的.pptx文件:錯誤消息+空幻燈片,我可以在最重要的信息曾經有:在標誌的地方腐敗的圖標!
我從我的模板和voilà刪除了標誌圖像,該文件是完全生成的。現在,如果我真的需要添加徽標圖像,我可以通過編程來完成。
謝謝!經過一個星期的嘗試意識到發生了什麼,我的一位好朋友使用Office 2010打開了該文件,然後我意識到徽標圖像在我原始的模板文件中已損壞。
謝謝:)
你的'foreach'中的'(...)'行是無效的C#。 – Kyle
謝謝:)這只是我用來替換幻燈片中文本的文本數據。 –