I am trying to generate a PowerPoint file containing a image using OpenXML. Unfortunately it does not work. The image is not being displayed. I've checked the file generated with the OpenXML productivity tool and I respectively unzipped the file contents. The file itself contains the image in /ppt/media/image.png and it should be displayed in the second slide.
Here's my code:
private void InsertSlide(string chartString, int position, string title, string text = "")
{
if (m_presentation == null || title == null || m_presentation.PresentationPart == null)
return;
var slide = new Slide(new CommonSlideData(new ShapeTree()));
var nonVisualProperties =
slide.CommonSlideData.ShapeTree.AppendChild(new NonVisualGroupShapeProperties());
nonVisualProperties.NonVisualDrawingProperties = new NonVisualDrawingProperties { Id = 1, Name = "" };
nonVisualProperties.NonVisualGroupShapeDrawingProperties = new NonVisualGroupShapeDrawingProperties();
nonVisualProperties.ApplicationNonVisualDrawingProperties = new ApplicationNonVisualDrawingProperties();
slide.CommonSlideData.ShapeTree.AppendChild(new GroupShapeProperties());
var slidePart = m_presentation.PresentationPart.AddNewPart<SlidePart>();
var imagePart = slidePart.AddImagePart(ImagePartType.Png, "irgendeinscheiss");
//var imageStream = new MemoryStream(Convert.FromBase64String(chartString));
using (var imageStream = new FileStream(#"C:\Users\DA\Desktop\Charts\1_Chart2_01.png", FileMode.Open))
{
imageStream.Position = 0;
imagePart.FeedData(imageStream);
}
slide.Save(slidePart);
var slideIdList = m_presentation.PresentationPart.Presentation.SlideIdList;
uint maxSlideId = 1;
SlideId prevSlideId = null;
foreach (SlideId slideId in slideIdList.ChildElements)
{
if (slideId.Id > maxSlideId)
maxSlideId = slideId.Id;
position--;
if (position == 0)
prevSlideId = slideId;
}
maxSlideId++;
SlidePart lastSlidePart;
if (prevSlideId != null)
lastSlidePart = (SlidePart)m_presentation.PresentationPart.GetPartById(prevSlideId.RelationshipId);
else
lastSlidePart = (SlidePart)m_presentation.PresentationPart.GetPartById(((SlideId)(slideIdList.ChildElements[0])).RelationshipId);
if (lastSlidePart.SlideLayoutPart != null)
slidePart.AddPart(lastSlidePart.SlideLayoutPart);
var newSlideId = slideIdList.InsertAfter(new SlideId(), prevSlideId);
newSlideId.Id = maxSlideId;
newSlideId.RelationshipId = m_presentation.PresentationPart.GetIdOfPart(slidePart);
m_presentation.PresentationPart.Presentation.Save();
}
Am I missing something? Maybe the relationships? After looking up 232243 thousand different examples, I am still stuck at this point. Thank you!
I think you need to add the image into the slide.CommonSlideData
public Slide InsertSlide(PresentationPart presentationPart, string layoutName)
{
UInt32 slideId = 256U;
// Get the Slide Id collection of the presentation document
var slideIdList = presentationPart.Presentation.SlideIdList;
if (slideIdList == null)
{
throw new NullReferenceException("The number of slide is empty, please select a ppt with a slide at least again");
}
slideId += Convert.ToUInt32(slideIdList.Count());
// Creates an Slide instance and adds its children.
Slide slide = new Slide(new CommonSlideData(new ShapeTree()));
SlidePart slidePart = presentationPart.AddNewPart<SlidePart>();
slide.Save(slidePart);
// Get SlideMasterPart and SlideLayoutPart from the existing Presentation Part
SlideMasterPart slideMasterPart = presentationPart.SlideMasterParts.First();
SlideLayoutPart slideLayoutPart = slideMasterPart.SlideLayoutParts.SingleOrDefault
(sl => sl.SlideLayout.CommonSlideData.Name.Value.Equals(layoutName, StringComparison.OrdinalIgnoreCase));
if (slideLayoutPart == null)
{
throw new Exception("The slide layout " + layoutName + " is not found");
}
slidePart.AddPart<SlideLayoutPart>(slideLayoutPart);
slidePart.Slide.CommonSlideData = (CommonSlideData)slideMasterPart.SlideLayoutParts.SingleOrDefault(
sl => sl.SlideLayout.CommonSlideData.Name.Value.Equals(layoutName)).SlideLayout.CommonSlideData.Clone();
// Create SlideId instance and Set property
SlideId newSlideId = presentationPart.Presentation.SlideIdList.AppendChild<SlideId>(new SlideId());
newSlideId.Id = slideId;
newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart);
return GetSlideByRelationShipId(presentationPart, newSlideId.RelationshipId);
}
/// <summary>
/// Get Slide By RelationShip ID
/// </summary>
/// <param name="presentationPart">Presentation Part</param>
/// <param name="relationshipId">Relationship ID</param>
/// <returns>Slide Object</returns>
private static Slide GetSlideByRelationShipId(PresentationPart presentationPart, StringValue relationshipId)
{
// Get Slide object by Relationship ID
SlidePart slidePart = presentationPart.GetPartById(relationshipId) as SlidePart;
if (slidePart != null)
{
return slidePart.Slide;
}
else
{
return null;
}
}
Public void InsertImageInLastSlide(Slide slide, string imagePath, string imageExt)
{
// Creates an Picture instance and adds its children.
P.Picture picture = new P.Picture();
string embedId = string.Empty;
embedId = "rId" + (slide.Elements().Count() + 915).ToString();
P.NonVisualPictureProperties nonVisualPictureProperties = new P.NonVisualPictureProperties(
new P.NonVisualDrawingProperties() { Id = (UInt32Value)4U, Name = "Picture 5" },
new P.NonVisualPictureDrawingProperties(new A.PictureLocks() { NoChangeAspect = true }),
new ApplicationNonVisualDrawingProperties());
P.BlipFill blipFill = new P.BlipFill();
Blip blip = new Blip() { Embed = embedId };
// Creates an BlipExtensionList instance and adds its children
BlipExtensionList blipExtensionList = new BlipExtensionList();
BlipExtension blipExtension = new BlipExtension() { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" };
UseLocalDpi useLocalDpi = new UseLocalDpi() { Val = false };
useLocalDpi.AddNamespaceDeclaration("a14",
"http://schemas.microsoft.com/office/drawing/2010/main");
blipExtension.Append(useLocalDpi);
blipExtensionList.Append(blipExtension);
blip.Append(blipExtensionList);
Stretch stretch = new Stretch();
FillRectangle fillRectangle = new FillRectangle();
stretch.Append(fillRectangle);
blipFill.Append(blip);
blipFill.Append(stretch);
// Creates an ShapeProperties instance and adds its children.
P.ShapeProperties shapeProperties = new P.ShapeProperties();
A.Transform2D transform2D = new A.Transform2D();
A.Offset offset = new A.Offset() { X = 457200L, Y = 1524000L };
A.Extents extents = new A.Extents() { Cx = 8229600L, Cy = 5029200L };
transform2D.Append(offset);
transform2D.Append(extents);
A.PresetGeometry presetGeometry = new A.PresetGeometry() { Preset = A.ShapeTypeValues.Rectangle };
A.AdjustValueList adjustValueList = new A.AdjustValueList();
presetGeometry.Append(adjustValueList);
shapeProperties.Append(transform2D);
shapeProperties.Append(presetGeometry);
picture.Append(nonVisualPictureProperties);
picture.Append(blipFill);
picture.Append(shapeProperties);
slide.CommonSlideData.ShapeTree.AppendChild(picture);
// Generates content of imagePart.
ImagePart imagePart = slide.SlidePart.AddNewPart<ImagePart>(imageExt, embedId);
FileStream fileStream = new FileStream(imagePath, FileMode.Open);
imagePart.FeedData(fileStream);
fileStream.Close();
}
Source Code
Related
I am trying to add an image to the word document using dotnet core and Open SDK library. Followed the exact same instruction as per the MSDN article. The code runs ok, but while trying to open document its says the document is corrupted.
Microsoft Doc
Used the OpenSDK Productivity tool and validated the document. Showing this error
Have confirmed that the Image Type are same. Not able to understand whats wrong.
private const string RefrenceKeyWord = "rId";
static void Main(string[] args)
{
InsertAPicture(document, fileName);
}
public static void InsertAPicture(string document, string fileName)
{
Int64Value imageWidth = 5731510L;
Int64Value imageHeight = 3820795L;
//using (var image = new Bitmap(fileName))
//{
// imageWidth = image.GetWidthInEMUs() / 10;
// imageHeight = image.GetHeightInEMUs() / 10;
//}
using (WordprocessingDocument wordprocessingDocument =
WordprocessingDocument.Open(document, true))
{
MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart;
ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Png);
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
imagePart.FeedData(stream);
}
//## start of new Code ##
var maxId = mainPart.Parts
.Where(p => p.RelationshipId.StartsWith(RefrenceKeyWord))
.Select(p =>
Convert.ToInt32(p.RelationshipId.Replace(RefrenceKeyWord,
"")))
.Max();
mainPart.ChangeIdOfPart(imagePart, $"{RefrenceKeyWord}{maxId + 1}");
//## end of new Code ##
AddImageToBody(wordprocessingDocument, mainPart.GetIdOfPart(imagePart), imageWidth, imageHeight);
}
}
private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId, Int64Value width, Int64Value height)
{
// Define the reference of the image.
var element =
new Drawing(
new DW.Inline(
new DW.Extent() { Cx = width, Cy = height },
new DW.EffectExtent()
{
LeftEdge = 0L,
TopEdge = 0L,
RightEdge = 2540L,
BottomEdge = 8255L
},
new DW.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Picture 1",
},
new DW.NonVisualGraphicFrameDrawingProperties(
new A.GraphicFrameLocks() { NoChangeAspect = true }),
new A.Graphic(
new A.GraphicData(
new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties()
{
Id = (UInt32Value)0U,
Name = "Picture 1"
},
new PIC.NonVisualPictureDrawingProperties(new A.PictureLocks() { NoChangeAspect = true, NoChangeArrowheads = true })),
new PIC.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}",
})
)
{
Embed = relationshipId,
//CompressionState =
//A.BlipCompressionValues.Print
},
new A.Stretch(
new A.FillRectangle())),
new PIC.ShapeProperties(
new A.Transform2D(
new A.Offset() { X = 0L, Y = 0L },
new A.Extents() { Cx = width, Cy = height }),
new A.PresetGeometry(
new A.AdjustValueList()
)
{ Preset = A.ShapeTypeValues.Rectangle }))
)
{ Uri = "https://schemas.openxmlformats.org/drawingml/2006/picture" })
)
{
DistanceFromTop = (UInt32Value)0U,
DistanceFromBottom = (UInt32Value)0U,
DistanceFromLeft = (UInt32Value)0U,
DistanceFromRight = (UInt32Value)0U,
EditId = "50D07946"
});
SectionProperties sectPr = (SectionProperties)wordDoc.MainDocumentPart.Document.Body.ChildElements.Last();
// var p = wordDoc.MainDocumentPart.RootElement;
// var p1 = wordDoc.MainDocumentPart.Document.Body.FirstChild;
var p1 = new Paragaph(new Run(element));
// Append the reference to body, the element should be in a Run.
wordDoc.MainDocumentPart.Document.Body.InsertBefore(p1, sectPr);
}
I have a cross platform app which I need to show a set of images when the user clic in a button, so, I put these image files named as "img000.png" to "img029.png" in a folder in the PCL solution and make al these images as "EmbeddedResource", after,I fill a List with all these images and its work fine at now, i.e. the image is shown like I want, but when I click in the button to show the next image in the list the image don't go to the next.
I have this:
//...
public class ImageSetPage : BasePage
// BasePage encapsule a ContentPage...
{
private string directory = "MyApp.Assets.";
private int idx = 0;
protected StackLayout _mainLayout;
protected StackLayout _buttonStack;
protected Image _btnPrevI;
protected Label _displayName;
protected Image _btnNestI;
protected Image _image;
protected List<Image> _Images;
public ImageSetPage()
{
this._Images = getImages();
var prevI_Tap = new TapGestureRecognizer();
prevI_Tap.Tapped += (s, e) =>
{
onClick("pvi");
};
var nextI_Tap = new TapGestureRecognizer();
nextI_Tap.Tapped += (s, e) =>
{
onClick("nti");
};
/// begin layout
base.Title = "set of Images";
this._mainLayout = new StackLayout()
{
Orientation = StackOrientation.Vertical,
BackgroundColor = Color.Black,
Padding = new Thickness(0, 10, 0, 0)
};
this._btnPrevI = new Image()
{
Aspect = Aspect.AspectFill,
Source = ImageSource.FromResource(directory+"prevbtn.png")
};
_btnPrevI.GestureRecognizers.Add(prevI_Tap);
this._displayName = new Label()
{
Style = Device.Styles.SubtitleStyle,
HorizontalOptions = LayoutOptions.CenterAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand,
TextColor = Color.White,
};
this._btnNextI = new Image()
{
Aspect = Aspect.AspectFill,
Source = ImageSource.FromResource(directory + "nextbtn.png")
};
_btnNextI.GestureRecognizers.Add(nextI_Tap);
this._buttonStack.Children.Add(_btnPrevI);
this._buttonStack.Children.Add(_displayName);
this._buttonStack.Children.Add(_btnNextI);
this._mainLayout.Children.Add(_buttonStack);
FillImage(idx);
this._mainLayout.Children.Add(this._image);
this.Content = this._mainLayout;
}
private void FillImage(int i)
{
this._displayName.Text = "Image n# " + FillWithZeroes(i);
// [EDIT 1] cemented these lines ...
// this._image = null;
// mi = _images[i];
// this._image = mi;
// [EDIT 2] the new try
string f = directory + "imgs.img0" + FillWithZeroes(i) + ".png";
this._image = new Image() {
VerticalOptions = LayoutOptions.Center,
Soruce = ImageSource.FromResource(f)
};
// In this way the image show and don't change when click
// this Fking* code is a big S_OF_THE_B*
// The Xamarin and the C# is brothers of this FKing* code
}
private void onClick(string v)
{
string vw = v;
if (vw.Equals("pvi")) idx--;
if (vw.Equals("nti")) idx++;
if (idx <= 0) idx = 29;
if (idx >= 29) idx = 0;
FillImage(idx);
vw = "";
}
private string FillWithZeroes(int v)
{
string s = v.ToString();
string r = "";
if (s.Length == 1) { r = "0" + s; } else { r = s; }
return r;
}
// to fill a list of Images with files in a PCL folder
private List<Image> getImages()
{
string directory = "MyApp.Assets.";
List<Image> imgCards = new List<Image>();
int c = 0;
for (c = 0; c < 30;c++) {
string f = directory + "imgs.img0" + FillWithZeroes(c) + ".png";
Image img = new Image();
img.Source = ImageSource.FromResource(f);
imgCards.Add(img);
}
return imgCards;
}
// ...
}
but the image don't change, i.e. change, like I see in debug, but don't show in the Layout when I click in the buttons.
Maybe I'm doing it wrong.
Can someone here help me?
thanks in advance
I'm trying to insert a signature image in a Word document created by a standard-letter generating application. I am using code adapted from various examples found on the web (see below). The application inserts the image, and the space in the document occupied by it is correct, but the image itself is not displayed.
I have tried it with both .png and .jpg images, but neither work; it doesn't appear to be a problem with the image itself.
I have examined the document using the OpenXml SDK Tool, which shows that the image is correctly embedded and encoded as a Base64 data string.
The problem that the SDK Tool does identify is that, compared to a document in which an image is manually inserted (and is correctly displayed), the pic:pic element in the document is rendered with the wrong namespace (a:pic) and it and all child controls are rendered as OpenXmlUnknownElement (see screenshot below).
Can anyone please tell me what is causing the incorrect namespace / element, and how to fix the problem?
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Drawing;
using System.Drawing.Imaging;
...
using A = DocumentFormat.OpenXml.Drawing;
using A14 = DocumentFormat.OpenXml.Office2010.Drawing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
using WP = DocumentFormat.OpenXml.Wordprocessing;
private void ReplacePlaceholderWithImage(MainDocumentPart mainDocumentPart, OpenXmlElement placeholder, string imagePath)
{
if (placeholder != null)
{
ImagePart ip = AddImagePart(mainDocumentPart, imagePath);
string relationshipId = mainDocumentPart.GetIdOfPart(ip);
var drawing = GetDrawing(relationshipId, imagePath);
placeholder.InsertAfterSelf(new WP.Paragraph(new WP.Run(drawing)));
placeholder.Remove();
Console.WriteLine("Picture inserted into picture content control successfully");
}
}
private ImagePart AddImagePart(MainDocumentPart mainDocumentPart, string imagePath)
{
var partType = GetPartTypeForImage(imagePath);
ImagePart ip = mainDocumentPart.AddImagePart(partType);
using (FileStream fileStream = File.Open(imagePath, FileMode.Open))
{
ip.FeedData(fileStream);
}
return ip;
}
private OpenXmlElement GetDrawing(string relationshipId, string imagePath)
{
//calculate dimensions
var size = GetImageDimensions(imagePath);
// Define the reference of the image.
return
new Drawing(
new DW.Inline(
new DW.Extent()
{
Cx = size.Width,
Cy = size.Height
},
new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
new DW.DocProperties() { Id = 1U, Name = "Picture 1" },
new DW.NonVisualGraphicFrameDrawingProperties(new A.GraphicFrameLocks() { NoChangeAspect = true, NoResize = true, NoSelection = true }),
new A.Graphic(new A.GraphicData(new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties()
{
Id = 0U,
Name = Path.GetFileName(imagePath)
},
new PIC.NonVisualPictureDrawingProperties()),
new A.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}"
}))
{
Embed = relationshipId,
CompressionState = A.BlipCompressionValues.Print
},
new A.Stretch(new A.FillRectangle())),
new A.ShapeProperties(
new A.Transform2D(new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = size.Width, Cy = size.Width }),
new A.PresetGeometry(new A.AdjustValueList()) { Preset = A.ShapeTypeValues.Rectangle })))
{
Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
}))
{
DistanceFromTop = 0U,
DistanceFromBottom = 0U,
DistanceFromLeft = 0U,
DistanceFromRight = 0U,
EditId = "50D07946"
});
}
private ImagePartType GetPartTypeForImage(string imagePath)
{
var img = GetImage(imagePath);
if (img.RawFormat.Equals(ImageFormat.Gif))
{
return ImagePartType.Gif;
}
else if (img.RawFormat.Equals(ImageFormat.Png))
{
return ImagePartType.Png;
}
else if (img.RawFormat.Equals(ImageFormat.Jpeg))
{
return ImagePartType.Jpeg;
}
else
{
throw new ApplicationException("Unexpected image type");
}
}
this issue stressed me up some hours and finally I found the reason. That's because the Drawing element Id need to be unique, you can't fix the ID like this
new DW.DocProperties() { Id = 1U, Name = "Picture 1" }
In my case, I have this function to set alt text and update the Id as well:
private static HashSet<uint> _drawingElementIds = new HashSet<uint>();
public static void SetPictureAltText(OpenXmlElement imageContainer, string altText)
{
var docPro = imageContainer.Descendants<DocProperties>().FirstOrDefault();
if (docPro != null)
{
//Make sure new image has unique ID, otherwise some images won't display
var newId = (uint)new Random().Next(10, 10000);
while (_drawingElementIds.Contains(newId))
{
newId = (uint)new Random().Next(10, 10000);
}
_drawingElementIds.Add(newId);
docPro.Id = new UInt32Value(newId);
docPro.Description = altText;
}
}
Cheers,
Nick
Watch your namespaces! I'm guessing you've copied from the same source as I did (which I'm sure was the Microsoft documentation), however the namespaces appear to be wrong in it for the following two properties:
A.BlipFill -> PIC.BlipFill
A.ShapeProperties -> PIC.ShapeProperties
Full code below:
var element = new Drawing(
new DW.Inline(
new DW.Extent()
{
Cx = 5657850L,
Cy = 3771900L
},
new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
new DW.DocProperties() { Id = 1U, Name = "Picture 1" },
new DW.NonVisualGraphicFrameDrawingProperties(new A.GraphicFrameLocks() { NoChangeAspect = true, NoResize = true, NoSelection = true }),
new A.Graphic(new A.GraphicData(new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties()
{
Id = 0U,
Name = "image.png"
},
new PIC.NonVisualPictureDrawingProperties()),
new PIC.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}"
}))
{
Embed = relationshipId,
CompressionState = A.BlipCompressionValues.Print
},
new A.Stretch(new A.FillRectangle())),
new PIC.ShapeProperties(
new A.Transform2D(new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = 5657850L, Cy = 3771900L }),
new A.PresetGeometry(new A.AdjustValueList()) { Preset = A.ShapeTypeValues.Rectangle })))
{
Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
}))
{
DistanceFromTop = 0U,
DistanceFromBottom = 0U,
DistanceFromLeft = 0U,
DistanceFromRight = 0U,
EditId = "50D07946"
});
I am using the following code to add a new slide to a ppt file and add an image. I am using Open XML 2.5 SDK.
A new slide is getting added but not the image. Is there anything wrong in this code?
int position = 1;
using (PresentationDocument presentationDocument = PresentationDocument.Open("c.pptx", true))
{
PresentationPart presentationPart = presentationDocument.PresentationPart;
Slide slide = new Slide(new CommonSlideData(new ShapeTree()));
NonVisualGroupShapeProperties nonVisualProperties = slide.CommonSlideData.ShapeTree.AppendChild(new NonVisualGroupShapeProperties());
nonVisualProperties.NonVisualDrawingProperties = new NonVisualDrawingProperties() { Id = 1, Name = "" };
nonVisualProperties.NonVisualGroupShapeDrawingProperties = new NonVisualGroupShapeDrawingProperties();
nonVisualProperties.ApplicationNonVisualDrawingProperties = new ApplicationNonVisualDrawingProperties();
// Specify the group shape properties of the new slide.
slide.CommonSlideData.ShapeTree.AppendChild(new GroupShapeProperties());
// Create the slide part for the new slide.
SlidePart slidePart = presentationPart.AddNewPart<SlidePart>();
// Save the new slide part.
slide.Save(slidePart);
string imgId = "rId" + new Random().Next(2000).ToString();
ImagePart imagePart = slidePart.AddImagePart(ImagePartType.Png, imgId);
using (FileStream stream = new FileStream("a.png", FileMode.Open))
{
stream.Position = 0;
imagePart.FeedData(stream);
}
slide.Save(slidePart);
// Modify the slide ID list in the presentation part.
// The slide ID list should not be null.
SlideIdList slideIdList = presentationPart.Presentation.SlideIdList;
// Find the highest slide ID in the current list.
uint maxSlideId = 1;
SlideId prevSlideId = null;
foreach (SlideId slideId in slideIdList.ChildElements)
{
if (slideId.Id > maxSlideId)
{
maxSlideId = slideId.Id;
}
position--;
if (position == 0)
{
prevSlideId = slideId;
}
}
maxSlideId++;
// Get the ID of the previous slide.
SlidePart lastSlidePart;
if (prevSlideId != null)
{
lastSlidePart = (SlidePart)presentationPart.GetPartById(prevSlideId.RelationshipId);
}
else
{
lastSlidePart = (SlidePart)presentationPart.GetPartById(((SlideId)(slideIdList.ChildElements[0])).RelationshipId);
}
// Use the same slide layout as that of the previous slide.
if (null != lastSlidePart.SlideLayoutPart)
{
slidePart.AddPart(lastSlidePart.SlideLayoutPart);
}
// Insert the new slide into the slide list after the previous slide.
SlideId newSlideId = slideIdList.InsertAfter(new SlideId(), prevSlideId);
newSlideId.Id = maxSlideId;
newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart);
// Save the modified prsentation.
presentationPart.Presentation.Save();
Thanks in advance.
I got the code for the Table in the powerpoint using the code generator, but I am not able to add the table to an existing powerpoint document.
I tried adding another table to the intended slide and doing the following:
Table table = slidePart.Slide.Descendants<Table>().First();
table.RemoveAllChildren();
Table createdTable = CreateTable();
foreach (OpenXmlElement childElement in createdTable.ChildElements)
{
table.AppendChild(childElement.CloneNode(true));
}
But that didn't work.
I am out of ideas on this issue.
My original target is to add a table with dynamic number of columns and fixed number of row to my presentation.
I know its been very long since this question is posted, but just in case if some one needs a working code to create table in pptx.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using A = DocumentFormat.OpenXml.Drawing;
using System.IO;
namespace ANF.Slides.TestEngine
{
class Program
{
static int index = 1;
static void Main(string[] args)
{
Console.WriteLine("Preparing Presentation");
PopulateData();
// GeneratedClass cls=new GeneratedClass();
//cls.CreatePackage(#"E:\output.pptx");
Console.WriteLine("Completed Presentation");
Console.ReadLine();
}
private static void PopulateData()
{
var overflow = false;
const int pageBorder = 3000000;
var db = new AdventureWorksEntities();
var products = db.Products;//.Take(5);
const string outputFile = #"E:\openxml\output.pptx";
File.Copy(#"E:\OpenXml\Template.pptx", outputFile, true);
using (var myPres = PresentationDocument.Open(outputFile, true))
{
var presPart = myPres.PresentationPart;
var slideIdList = presPart.Presentation.SlideIdList;
var list = slideIdList.ChildElements
.Cast<SlideId>()
.Select(x => presPart.GetPartById(x.RelationshipId))
.Cast<SlidePart>();
var tableSlidePart = (SlidePart)list.Last();
var current = tableSlidePart;
long totalHeight = 0;
foreach (var product in products)
{
if (overflow)
{
var newTablePart = CloneSlidePart(presPart, tableSlidePart);
current = newTablePart;
overflow = false;
totalHeight = 0;
}
var tbl = current.Slide.Descendants<A.Table>().First();
var tr = new A.TableRow();
tr.Height = 200000;
tr.Append(CreateTextCell(product.Name));
tr.Append(CreateTextCell(product.ProductNumber));
tr.Append(CreateTextCell(product.Size));
tr.Append(CreateTextCell(String.Format("{0:00}", product.ListPrice)));
tr.Append(CreateTextCell(product.SellStartDate.ToShortDateString()));
tbl.Append(tr);
totalHeight += tr.Height;
if (totalHeight > pageBorder)
overflow = true;
}
}
}
static SlidePart CloneSlidePart(PresentationPart presentationPart, SlidePart slideTemplate)
{
//Create a new slide part in the presentation
SlidePart newSlidePart = presentationPart.AddNewPart<SlidePart>("newSlide" + index);
index++;
//Add the slide template content into the new slide
newSlidePart.FeedData(slideTemplate.GetStream(FileMode.Open));
//make sure the new slide references the proper slide layout
newSlidePart.AddPart(slideTemplate.SlideLayoutPart);
//Get the list of slide ids
SlideIdList slideIdList = presentationPart.Presentation.SlideIdList;
//Figure out where to add the next slide (find max slide)
uint maxSlideId = 1;
SlideId prevSlideId = null;
foreach (SlideId slideId in slideIdList.ChildElements)
{
if (slideId.Id > maxSlideId)
{
maxSlideId = slideId.Id;
prevSlideId = slideId;
}
}
maxSlideId++;
//Add new slide at the end of the deck
SlideId newSlideId = slideIdList.InsertAfter(new SlideId(), prevSlideId);
//Make sure id and relid is set appropriately
newSlideId.Id = maxSlideId;
newSlideId.RelationshipId = presentationPart.GetIdOfPart(newSlidePart);
return newSlidePart;
}
private static A.TableCell CreateTextCell(string text)
{
var textCol = new string[2];
if (!string.IsNullOrEmpty(text))
{
if (text.Length > 25)
{
textCol[0] = text.Substring(0, 25);
textCol[1] = text.Substring(26);
}
else
{
textCol[0] = text;
}
}
else
{
textCol[0] = string.Empty;
}
A.TableCell tableCell3 = new A.TableCell();
A.TextBody textBody3 = new A.TextBody();
A.BodyProperties bodyProperties3 = new A.BodyProperties();
A.ListStyle listStyle3 = new A.ListStyle();
textBody3.Append(bodyProperties3);
textBody3.Append(listStyle3);
var nonNull = textCol.Where(t => !string.IsNullOrEmpty(t)).ToList();
foreach (var textVal in nonNull)
{
//if (!string.IsNullOrEmpty(textVal))
//{
A.Paragraph paragraph3 = new A.Paragraph();
A.Run run2 = new A.Run();
A.RunProperties runProperties2 = new A.RunProperties() { Language = "en-US", Dirty = false, SmartTagClean = false };
A.Text text2 = new A.Text();
text2.Text = textVal;
run2.Append(runProperties2);
run2.Append(text2);
paragraph3.Append(run2);
textBody3.Append(paragraph3);
//}
}
A.TableCellProperties tableCellProperties3 = new A.TableCellProperties();
tableCell3.Append(textBody3);
tableCell3.Append(tableCellProperties3);
//var tc = new A.TableCell(
// new A.TextBody(
// new A.BodyProperties(),
// new A.Paragraph(
// new A.Run(
// new A.Text(text)))),
// new A.TableCellProperties());
//return tc;
return tableCell3;
}
}
}