C# OpenXML documentation understand animations in PowerPoint - c#

I try to get animations from PowerPoint presentations, using DocumentFormat.OpenXml.dll. Which I tried is:
using (PresentationDocument presentationDocument = PresentationDocument.Open(pptPath, true))
{
var slidepart = presentationDocument.PresentationPart.SlideParts.First();
var slide = slidepart.Slide;
var xml = slide.OuterXml;
}
to get the first slide's XML. But I can't understand the entire XML structure and specific the animations tags.
Is there any good documentations about that, or some samples?
EDIT: I found next documentations and I started to read them:
Open XML SDK in GitHub
officeopenxml.com
Thank you!

Related

OpenXml. How to add creator using C# in docx?

I am trying to add some core properties to the Docx document. I have found only one example in different places of how it can be done.
For instance here. But there is a problem.
If we look at the structure of the Docx itself created by Word application and using OpenXml, there is a difference between them.
Structure of the docx created using openxml and document.PackageProperties.Creator = "vso"
Moreover, validation of the file can't be succeeded if I want to check the file by productivity tool from Microsoft. Of course, the word can read this file, but it is not a proper way to generate a word file from my point of view.
Here you can see the structure of the docx created by the word application itself
One more aspect, if I write following:
CoreFilePropertiesPart corePackageProperties = document.CoreFilePropertiesPart;
if (corePackageProperties == null)
{
corePackageProperties = document.AddCoreFilePropertiesPart();
}
then core.xml file is created in the proper place of structure, but it is empty.
So, the question is does OpenXML SDK have the way to get the structure of the docx the same as using the word application itself?
Microsoft documentation suggests :
using (XmlTextWriter writer = new XmlTextWriter(coreFilePropPart.GetStream(FileMode.Create), System.Text.Encoding.UTF8))
{
writer.WriteRaw("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<cp:coreProperties xmlns:cp=\"https://schemas.openxmlformats.org/package/2006/metadata/core-properties\"></cp:coreProperties>");
writer.Flush();
}
I had the same issue when creating an Excel file and this sort it out.

Copy slide containing notes from one PowerPoint presentaition to another with OpenXML SDK

I am trying to copy slides from one PowerPoint presentation to another. I have used the procedure outlined in the following article, and it generally works fine.
https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2007/ee361883(v=office.12)?redirectedfrom=MSDN
However, when the slide to be copied contains notes, the resulting presentation after copying is corrupted. I've noticed that the code generates a new notesMaster which is not added to the notesMasterIdLst in presentation.xml, and have a suspicion this might be the issue. However, I cannot add the new notes master to the presentation, as a presentation can only have one notesMaster.
According to the Microsoft Documentation, Open XML SDK is defined this way:
The Open XML SDK 2.5 simplifies the task of manipulating Open XML
packages and the underlying Open XML schema elements within a package.
The Open XML SDK 2.5 encapsulates many common tasks that developers
perform on Open XML packages, so that you can perform complex
operations with just a few lines of code.
It looks like it is not easy to solve your problem using the Open XML SDK. If you use Aspose.Slides for .NET you will copy a slide with its notes as shown below:
var sourceFileName = "example1.pptx";
var targetFileName = "example2.pptx";
var slideIndex = 0;
using (var sourcePresentation = new Presentation(sourceFileName))
using (var targetPresentation = new Presentation(targetFileName))
{
var slide = sourcePresentation.Slides[slideIndex];
targetPresentation.Slides.AddClone(slide);
targetPresentation.Save(targetFileName, SaveFormat.Pptx);
}
You can also evaluate Aspose.Slides Cloud for presentation manipulating. This REST-based API allows you to make 150 free API calls per month for API learning and presentation processing. The following code example shows you how to do the same using Aspose.Slides Cloud:
var slidesApi = new SlidesApi("my_client_id", "my_client_key");
var sourceFileName = "example1.pptx";
var targetFileName = "example2.pptx";
var slideIndex = 1;
using (var sourceStream = File.OpenRead(sourceFileName))
slidesApi.UploadFile(sourceFileName, sourceStream);
using (var targetStream = File.OpenRead(targetFileName))
slidesApi.UploadFile(targetFileName, targetStream);
slidesApi.CopySlide(targetFileName, slideIndex, null, sourceFileName);
using (var resultStream = slidesApi.DownloadFile(targetFileName))
using (var fileStream = File.OpenWrite(targetFileName))
resultStream.CopyTo(fileStream);
I work as a Support Developer at Aspose.
I believe I managed to solve this issue by doing the following steps:
Make the source presentations editable when opening them:
using (PresentationDocument mySourceDeck =
PresentationDocument.Open(
presentationFolder + sourcePresentation, true))
{
PresentationPart sourcePresPart =
mySourceDeck.PresentationPart;
Copy the notes slide CommonSlideData from the slide, then delete the notes slide part from the slide:
sp = (SlidePart)sourcePresPart.GetPartById(slideId.RelationshipId);
CommonSlideData notesSlideData = null;
if (sp.NotesSlidePart != null)
{
notesSlideData = (CommonSlideData)sp.NotesSlidePart.NotesSlide.CommonSlideData.CloneNode(true);
sp.DeletePart(sp.NotesSlidePart);
}
Readd any existing notes slide data by adding a new NotesSlidePart to the copied slide (now added to the target presentation and called destSp), adding relationship parts and a new NotesSlide object initialised with the copied notes slide data.
if (notesSlideData != null)
{
NotesSlidePart notesSlidePart1 = destSp.AddNewPart<NotesSlidePart>();
notesSlidePart1.AddPart(destSp);
notesSlidePart1.AddPart(destPresPart.NotesMasterPart);
NotesSlide notesSlide = new NotesSlide(notesSlideData);
notesSlidePart1.NotesSlide = notesSlide;
}
Warning: The notes slides will be deleted from the source presentation files, so you might want to make a copy of them first, or add them back to the presentation after it has been copied/merged.
This seems to retain at least some existing formatting of the notes slides, such as bold text. However, I have not yet tested this on a lot of different presentations so I suppose there could be some issues if the notes slides are based on very different notes slide masters, but I'm not sure.
Related to this, I ran into a similar issue after getting the notes slides to work, which seemed to be because of any custom xml parts that existed on the presentation to be copied. These presentations worked after adding some code to add relationships to the copied presentation's CustomXmlPart to the target presentation:
foreach (var customXmlPart in destSp.GetPartsOfType<CustomXmlPart>())
{
destPresPart.AddPart(customXmlPart);
}

How do I copy content from Word Document another with images and links?

I've had some problem when copying content from a Word document to another Word document.
The document where the information should end up in have a header.
So far I have managed to copy the content to the second document and not affecting the header.
However I can't figure out how to bind the relationships for links and Images.
This is my code so far:
public static void AddContentToTemplateCopy(
string sourceDocumentPath, string endDocumentPath)
{
using (WordprocessingDocument sourceDoc =
WordprocessingDocument.Open(sourceDocumentPath, false))
using (WordprocessingDocument endDoc =
WordprocessingDocument.Open(endDocumentPath, true))
{
var sourceMainPart = sourceDoc.MainDocumentPart;
var sourceBody = sourceMainPart.Document.Body;
var endSection = endDoc.MainDocumentPart.Document.Body.Elements<SectionProperties>();
var endDocMainPart = endDoc.MainDocumentPart;
var sourceBodyClone = sourceBody.CloneNode(true);
sourceBodyClone.ReplaceChild(endSection.FirstOrDefault().CloneNode(true), sourceBodyClone.Elements<SectionProperties>().FirstOrDefault());
endDocMainPart.Document.ReplaceChild(sourceBodyClone, endDocMainPart.Document.Body);
foreach (HyperlinkRelationship link in sourceMainPart.HyperlinkRelationships)
{
endDocMainPart.AddHyperlinkRelationship(link.Uri, link.IsExternal, link.Id);
}
}
I get the following Error : 'rId6' ID conflicts with the ID of an existing relationship for the specified source.
And the if i have a Image in the content it can't be displayed.
If I zip the document and look at the files in the package I can find the Image but for the same reason as the links the Relation
So my question is: How do I bind the links and Images with their "_rels" references? or how do I copy them so that it works..
This is a Relationship link when I have added the link by hand.
<Relationship Target="media/image1.jpg" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Id="rId11"/>
A picture to show that the link text is copied but have no formatting and that the image can't be displayed.
Thanks to the answer by JasonPlutext i managed to use OpenXML PowerTools (Version 2.2). Keep in mind that the .Net version is 3.5 when importing the project. You Might need to change it. (Supports Open XML 2.5 as well from what I've noticed)
Very simple to create new documents and take parts from old documents.
The code here is in my case where I want the formatting and content from one and then the Header from a template document. The order matters.
Hopefully this will save time for others with the same problem.
public static void AddContentToTemplateCopy(string templateDocumentPath,
string contentDocumentPath,
List<Source> sources,
string outName)
{
sources = new List<Source>()
{
new Source(new WmlDocument(contentDocumentPath),false),
new Source(new WmlDocument(templateDocumentPath),true),
};
DocumentBuilder.BuildDocument(sources, outName);
}
You might find it easier to try Eric White's document builder.

Using the OpenXml SDK 2.0 to insert tables in a word document

I am just starting out with the OpenXML SDK 2.0 in Visual Studio 2010 (C#). I have automated office programs before using COM automation, which was painful.
I have a template made by one of our graphic designers, which will provide the foundation for my reports. In order to automate the simple things (plaintext items) I have added content controls to the template and bound a custom XML part to the doc. The content controls are as follows:
DayCount
AlternateJobTitle
Date
SignatureName
After making a copy of the template, I then edit the content controls and save the file with the following code:
//stand up object that reads the Word doc package
using (WordprocessingDocument doc = WordprocessingDocument.Open(docOutputPath, true))
{
//create XML string matching custom XML part
string newXml = "<root>" +
"<DayCount>42</DayCount>" +
"<AlternateJobTitle>Supervisor</AlternateJobTitle>" +
"<Date>9/24/2012</Date>" +
"<SignatureName>John Doe</SignatureName>" +
"</root>";
MainDocumentPart main = doc.MainDocumentPart;
main.DeleteParts<CustomXmlPart>(main.CustomXmlParts);
//add and write new XML part
CustomXmlPart customXml = main.AddCustomXmlPart(CustomXmlPartType.CustomXml);
using (StreamWriter ts = new StreamWriter(customXml.GetStream()))
{
ts.Write(newXml);
}
}
This all works well. However, my document is not made up solely of standard text and plaintext updates. The real meat of the report is in a number of tables that need to be added to each report as well. I have been searching like crazy for a good description on how this is done, but have really not found anything. Is there some way to delineate where to place a table using the same content control logic used for plaintext controls? Any code samples I have found of creating a table using OpenXML have just assumed that you want to append it to the end of the main document part. I would like to specify where the tables need to go in the template, generate the tables and place them in the specified regions of the template. Is this possible?
Any help is greatly appreciated.
There are a lot of OpenXml creation questions. But if you decide to take this path - answer is general - examine OpenXml Productivity Tool. At my PC it could be found at "C:\Program Files (x86)\Open XML SDK\V2.0\tool\OpenXmlSdkTool.exe". Just create in MsWord document which you want to create using OpenXml and reflect document's code using this tool. Good luck!
If you need to display tabled data, so far, the best thing I found is Word Document Generator at http://worddocgenerator.codeplex.com/.

Creating an Open XML file in .NET - schema

I'm trying to make a report generator inside of a C# application for my boss, I came across this page and looked into RichTextBoxes and think that I can build on this idea to do what my boss is looking for. http://openxmldeveloper.org/articles/OpenXMLDocFromDotNet.aspx
The issue I'm running into is their example code for the XML portion assumed you were creating an application in an Office 2007 beta. The schema listed here doesn't work for retail Office 2007. Can anyone show me where I can look to find out more about schema in general, or explain what the code is doing here? Alternatively, if anyone has a different suggestion for creating a .docx file based on the contents of a rich text box, that would be greatly appreciated. I found different resources that offered advice similar to this: http://nishantrana.wordpress.com/2007/11/03/creating-word-document-using-c/
But I kept having issues getting it to recognize what a WordApp was.
Here's the code from the first link with the schema issues.
private void GenerateDocument_Click(object sender, EventArgs e)
{
string _nameSpaceURI = "http://schemas.microsoft.com/office/word/2005/10/wordml";
string docFileName = GetSavePath();
//-- Step 1 - Creating the document xml
XmlDocument doc = new XmlDocument();
XmlElement _wWordDoc = doc.CreateElement("w:wordDocument", _nameSpaceURI);
doc.AppendChild (_wWordDoc);
XmlElement _wbody = doc.CreateElement("w:body",_nameSpaceURI);
_wWordDoc.AppendChild(_wbody);
// Check if the string contains a line feed
string[] _SplitStr = mleTextForDocument.Text.Split('\n');
// if it contains line feed then each entry with a line feed goes to a new paragraph.
for (int row = 0; row < _SplitStr.Length; row++)
{
XmlElement _wp1 = doc.CreateElement("w:p",_nameSpaceURI);
_wbody.AppendChild(_wp1);
XmlElement _wr1 = doc.CreateElement("w:r", _nameSpaceURI);
_wp1.AppendChild(_wr1);
XmlElement _wt11 = doc.CreateElement("w:t", _nameSpaceURI);
_wr1.AppendChild(_wt11);
XmlNode _wt1 = doc.CreateNode(XmlNodeType.Text, "w:t",_nameSpaceURI);
_wt1.Value = _SplitStr[row];
_wt11.AppendChild(_wt1);
}
//-- Step 2 - Creating the Package
Package package = null;
package = Package.Open(docFileName, FileMode.Create, FileAccess.ReadWrite);
//-- Step 3 - Create the main document part (document.xml)
Uri uri = new Uri("/word/document.xml", UriKind.Relative);
PackagePart part = package.CreatePart(uri, "application/vnd.ms-word.main+xml");
StreamWriter partWrt = new StreamWriter(part.GetStream(FileMode.Create, FileAccess.Write));
doc.Save(partWrt);
partWrt.Close();
package.Flush();
//-- Step 4 - Create the relationship file
uri = new Uri("/word/document.xml", UriKind.Relative);
PackageRelationship rel = package.CreateRelationship(uri, TargetMode.Internal, "http://schemas.microsoft.com/office/2006/relationships/officeDocument", "rId1");
package.Flush();
//-- Step 5- Close the document.
package.Close();
}
I'm sorry for the lack of a clear question, but I really don't know what question to ask. I've never used schemas before, never used XML, and never had to add references to my projects before. Any advice or suggestions are appreciated.
Dispite the ambigious question, and apparently it's coming from my bizzaro evil twin (nwonknu) (elgoog), joke right.
Anyhow, I've said it before and I'll say it again THE source of quality advise for XML/OpenXML is Eric White. He's a very active blogger, looks like 4+ years of consistant postings (sux when good sources just evaporate sometimes), anyhow breeze through his blog for a few minutes and I'm sure your grasp of OpenXML + Linq 2 XML will be a bit more solid.

Categories

Resources