Group Forums >> web developers and designers >> Exporting Data to PowerPoint from VB.NET Web Page

Rate

Exporting Data to PowerPoint from VB.NET Web Page

547 Views
13 Replies Flag as inappropriate
120-overwatch_max50

30 posts

back to top

Posted 7 months ago

 

All,


I have currently been assigned a project to take reports that I have generated and convert them to a power point slide with the push of one button on the Page itself. Does anyone have any advice on how to accomplish this task or where to look? I am using Visual Studio 2005 for this project.


 


Thanks in Advance


James Cassidy

0 posts

back to top
Rate

Rate This | Posted 7 months ago

 

I have no clue, good luck.

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Ok,


So far I have narrowed it down to two possibilities. VSTO 2.0 which comes with Visual Studio 2005. 3.0 comes with Visual Studio 2008 and has web capabilities but I have 2005. Or the other possibility is an office COM. The only thing is I have not had to use COM references with a web page before. I will keep everyone posted on how all this pans out. Last resort is I will tell my boss to get me Visual Studio 2008.


James Cassidy

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

It turns out that VSTO will do everything you want to do as far as Visual Studio projects and Office products. It works with both Web and Win32/64 apps. I am not sure yet how all of this is done but I will update as I learn more. =-)


James 

0 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Thanks. I will have learned something new today, and I will fall asleep less dumb.

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Update,


In order for you to use VSTO you must have a form of Visual Studio with the capability to use C# or Visual Basic, and Office Professional 2003 to current. Both must be installed on the system before you take the last step of preparing your machine to use VSTO. The last step is you need to go to the Microsoft Download Page for the "Visual Studio Tools for Office". This is a 6MB file. When installed you will notice the "Visual Studio Tools for Office Sec...." on the load screen of Visual Studio.


The URL for the download:


http://www.microsoft.com/downloads/details.aspx?FamilyId=5E86CAB3-6FD6-4955-B979-E1676DB6B3CB&displaylang=en


If you do not have Office Pro 2003 to current you will absolutely have to use COM references and Macros.


James


 

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Update,


Imports System.IO.Packaging 'Will not load or does not have publick classes


This import statement was anoying me as you can see from the comment following it. I spent 3 days trying to figure out how to get it to properly import. Here is the answer on how to import the System.IO.Package namespace.


If you are doing a Win32 App go to Project > Add Reference... via the Project menu item at the top of the screen.


If you are doing a Website go to Website > Add Reference... via the Website menu at the top of the screen.


At this point make sure you have the .NET tab selected and look for the WindowsBase.dll and select it. If it is not there do the following.


Go to the Browse Tab and browse to C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0 and select the WindowsBase.dll.


This process is critical to using the VSTO code and for some reason it is assumed everywhere you go for information that this is common knowledge.


This import statement will allow you to modify Office 2007 documents without ever actually opening them. This is done by accessing the XML files that make up the document.


To view the XML files that make up the document make sure it is the 2007 document format. For example the PowerPoint 2003 extension is filename.ppt. What you want is filename.pptx. Take that file name and add .zip to it. Example: filename.pptx.zip. Then open the .zip folder and copy the files and past them outside the .zip file. Open Internet Explorer and go to the menu and select open. In the drop down box at the bottom of the browse window select all files. navigate to the unzipped folders and open any of the documents located within. There you go the XML documents making up the file.


Now all that I need to learn now is the best way of updating those XML docs. =-)


James

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Update,


Ok, I have cracked this egg wide open and now know how to modify slides from code on a VB.NET web page. Here is what you need to do.


Import the following:


Imports Microsoft.VisualBasic 'This import should already be in your class when you create it.


Imports System.IO


Imports System.IO.Packaging


Imports System.Collections.Generic


Imports System.Text


Imports System.Linq


Imports System.Xml


Imports DocumentFormat.OpenXml


Imports DocumentFormat.OpenXml.Presentation


Imports DocumentFormat.OpenXml.Packaging


When you import all of these you will see that some of them say they do not exist. You need to Reference the Following.


Go to the menu and click Website > Add Reference.  Add DocumentFormat.OpenXml. You will need to do as stated in the above post to reference the WindowBase.dll. Browes to the same area but instead pick the v3.5 folder and select all the .dll files to add to your project. You are now set to program for Office Documents. I am currently making a page that will accept requests from other pages to build documents. In the following Posts I will give the foundation code to accomplish certain tasks.


James

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Here is the code to replace a picture in a PowerPoint Slide:


Public Sub PPTReplaceImageOnSlide(ByVal fileName As String, ByVal slideTitle As String, ByVal imagePath As String)

' Given a slide deck name and a slide title within the deck,
' replace the first image on the slide with the supplied image.
' If the slide doesn't have an image on it, do nothing.

Const documentRelationshipType As String = _
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
Const slideRelationshipType As String = _
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"
Const imageRelationshipType As String = _
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
Const imageContentType As String = "image/jpeg"

Const presentationmlNamespace As String = _
"http://schemas.openxmlformats.org/presentationml/2006/main"
Const drawingmlNamespace As String = _
"http://schemas.openxmlformats.org/drawingml/2006/main"
Const relationshipNamespace As String _
= "http://schemas.openxmlformats.org/officeDocument/2006/relationships"

Dim documentPart As PackagePart = Nothing
Using pptPackage As Package = Package.Open(fileName, FileMode.Open,_
FileAccess.ReadWrite)
' Get the main document part (presentation.xml).
For Each documentRelationship As PackageRelationship In _
pptPackage.GetRelationshipsByType(documentRelationshipType)
Dim documentUri As Uri = PackUriHelper.ResolvePartUri(New Uri("/",_
UriKind.Relative), documentRelationship.TargetUri)
documentPart = pptPackage.GetPart(documentUri)
' There is only one document.
Exit For
Next

' Manage namespaces to perform Xml XPath queries.
Dim nt As New NameTable()
Dim nsManager As New XmlNamespaceManager(nt)
nsManager.AddNamespace("p", presentationmlNamespace)
nsManager.AddNamespace("a", drawingmlNamespace)
nsManager.AddNamespace("r", relationshipNamespace)

Dim slidePart As PackagePart = Nothing
Dim slideUri As Uri = Nothing

' Select each slide document part (slides/slideX.xml)
' via relationship with document part.
For Each slidePartRelation As PackageRelationship In_
documentPart.GetRelationshipsByType(slideRelationshipType)
slideUri = PackUriHelper.ResolvePartUri(documentPart.Uri,_
slidePartRelation.TargetUri)
slidePart = pptPackage.GetPart(slideUri)

' Get the slide part from the package.
Dim slideDoc As XmlDocument = New XmlDocument(nt)
slideDoc.Load(slidePart.GetStream())

' Locate the slide title using XPath.
Dim titleNode As XmlNode = slideDoc.SelectSingleNode("//p:sp//p:ph _
[@type='title' or @type='ctrTitle']", nsManager)
If titleNode IsNot Nothing Then
Dim titleText As String = _
titleNode.ParentNode.ParentNode.ParentNode.InnerText

' Perform a case-insensitive comparison.
If String.Compare(titleText, slideTitle, True) = 0 Then
' Found a match. Modify this slide.
Dim imagePart As PackagePart = Nothing

' Look through the slide's relationships to see if
' there's an image in there:
For Each imagePartRelation As PackageRelationship In_
slidePart.GetRelationshipsByType(imageRelationshipType)
Dim imageUri As Uri = _
PackUriHelper.ResolvePartUri(slidePart.Uri,_
imagePartRelation.TargetUri)
imagePart = pptPackage.GetPart(imageUri)
'
'
'
'
If imagePart IsNot Nothing Then
' You've got an image!
Dim oldRelID As String = imagePartRelation.Id

' Create a part for the new image
' (Be warned: If the package already contains
' a part with this name (unlikely), you wouldn't be able
' to create the new part):
Dim imageFile As String = Path.GetFileName(imagePath)
Dim newImageUri As Uri = New _
Uri("/ppt/media/" & imageFile, UriKind.Relative)
Dim newImagePart As PackagePart = _
pptPackage.CreatePart(newImageUri, imageContentType)

'Now copy the bytes into the new part
Using outputStream As Stream = _
newImagePart.GetStream(FileMode.Create, FileAccess.Write)
Using inputStream As New _
FileStream(imagePath, FileMode.Open, FileAccess.Read)
Dim len As Integer = _
Convert.ToInt32(inputStream.Length)
Dim bytes(0 To len - 1) As Byte
Dim bytesRead As Integer = _
inputStream.Read(bytes, 0, len)
If bytesRead = len Then
outputStream.Write(bytes, 0, len)
End If
End Using
End Using

' Create a relationship to the new part:
Dim newRelation As PackageRelationship = _
slidePart.CreateRelationship( _
newImageUri, TargetMode.Internal, imageRelationshipType)
Dim newRelId As String = newRelation.Id

' Update the relationship in the slide XML:
Dim searchString As String = _
String.Format("//p:pic//a:blip[@r:embed='{0}']", oldRelID)
Dim relNode As XmlNode = slideDoc.SelectSingleNode _
(searchString, nsManager)
If relNode IsNot Nothing Then
relNode.Attributes("r:embed").Value = newRelId
End If

' Delete the old relationship.
' PowerPoint will clean up the orphaned
' image part on the next save.slidePart.DeleteRelationship
' (oldRelID);

' Only update the first image you run across.
Exit For

' Only update the first image you run across:
Exit For
End If
Next

' Reset the stream, and save the slide XML back to its part.
slideDoc.Save(slidePart.GetStream(FileMode.Create, FileAccess.Write))

' Only modify the first slide that matches the
' specified title.
Exit For

End If
End If
Next

End Using
End Sub

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Looks like the code may need to go though a bit of reformatting once you paste it in the editor. =-)


James

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Here is the code to insert a slide into a .pptx. I am currently working on the code to delete a slide from the presentation.


Public Sub InsertNewSlide(ByVal presentationFile As String, ByVal position As Integer, ByVal slideTitle As String)

' Open the source document as read/write.
Dim presentationDoc As PresentationDocument = PresentationDocument.Open(presentationFile, True)

Using (presentationDoc)

'Pass the source document and the position and title of the slide to be inserted to the next method.
InsertNewSlide(presentationDoc, position, slideTitle)

End Using

End Sub

Private Sub InsertNewSlide(ByVal presentationDocument As PresentationDocument, ByVal position As Integer, ByVal slideTitle As String)
If (presentationDocument Is Nothing) Then
Throw New ArgumentNullException("presentationDocument")
End If
If (slideTitle Is Nothing) Then
Throw New ArgumentNullException("slideTitle")
End If

Dim presentationPart As PresentationPart = presentationDocument.PresentationPart

' Verify that the presentation is not empty.
If (presentationPart Is Nothing) Then
Throw New InvalidOperationException("The presentation document is empty.")
End If

' Declare and instantiate a new slide.
Dim slide As Slide = New Slide(New CommonSlideData(New ShapeTree))
Dim drawingObjectId As UInteger = 1

' Construct the slide content.
' Specify the non-visual properties of the new slide.
Dim nonVisualProperties As DocumentFormat.OpenXml.Presentation.NonVisualGroupShapeProperties = slide.CommonSlideData.ShapeTree.AppendChild(New DocumentFormat.OpenXml.Presentation.NonVisualGroupShapeProperties())

nonVisualProperties.NonVisualDrawingProperties = New DocumentFormat.OpenXml.Presentation.NonVisualDrawingProperties()
With nonVisualProperties.NonVisualDrawingProperties
.Id = 1
.Name = ""
End With

nonVisualProperties.NonVisualGroupShapeDrawingProperties = New DocumentFormat.OpenXml.Presentation.NonVisualGroupShapeDrawingProperties()
nonVisualProperties.AppNonVisualDrawingProperties = New AppNonVisualDrawingProperties()

' Specify the group shape properties of the new slide.
slide.CommonSlideData.ShapeTree.AppendChild(New DocumentFormat.OpenXml.Presentation.GroupShapeProperties())
' Declare and instantiate the title shape of the new slide.
Dim titleShape As DocumentFormat.OpenXml.Presentation.Shape = slide.CommonSlideData.ShapeTree.AppendChild(New DocumentFormat.OpenXml.Presentation.Shape())
drawingObjectId = (drawingObjectId + 1)

' Specify the required shape properties for the title shape.

Dim nvdpNonVisualDrawingProperties As New DocumentFormat.OpenXml.Presentation.NonVisualDrawingProperties()
With nvdpNonVisualDrawingProperties
.Id = drawingObjectId
.Name = "Title"
End With

Dim slShapeLocks As New Drawing.ShapeLocks()
With slShapeLocks
.NoGrouping = True
End With

Dim psPlaceholderShape As New PlaceholderShape()
With psPlaceholderShape
.Type = PlaceholderValues.Title
End With

titleShape.NonVisualShapeProperties = New DocumentFormat.OpenXml.Presentation.NonVisualShapeProperties(nvdpNonVisualDrawingProperties, New DocumentFormat.OpenXml.Presentation.NonVisualShapeDrawingProperties(slShapeLocks), New AppNonVisualDrawingProperties(psPlaceholderShape))

titleShape.ShapeProperties = New DocumentFormat.OpenXml.Presentation.ShapeProperties()

Dim dtDrawingText As New Drawing.Text()
With dtDrawingText
.Text = slideTitle
End With

' Specify the text of the title shape.
titleShape.TextBody = New DocumentFormat.OpenXml.Presentation.TextBody(New Drawing.BodyProperties, New Drawing.ListStyle, New Drawing.Paragraph(New Drawing.Run(dtDrawingText)))

' Declare and instantiate the body shape of the new slide.
Dim bodyShape As DocumentFormat.OpenXml.Presentation.Shape = slide.CommonSlideData.ShapeTree.AppendChild(New DocumentFormat.OpenXml.Presentation.Shape())
drawingObjectId = (drawingObjectId + 1)

' Specify the required shape properties for the body shape.
Dim nvdp As New NonVisualDrawingProperties()
With nvdp
.Id = drawingObjectId
.Name = "ContentPlaceholder"
End With

Dim slShapeLocks2 As New Drawing.ShapeLocks()
With slShapeLocks2
.NoGrouping = True
End With

Dim psPlaceHolderShape2 As New PlaceholderShape()
With psPlaceHolderShape2
.Index = 1
End With

bodyShape.NonVisualShapeProperties = New NonVisualShapeProperties(nvdp, New NonVisualShapeProperties(slShapeLocks2), New AppNonVisualDrawingProperties(psPlaceHolderShape2))

bodyShape.ShapeProperties = New ShapeProperties()

' Specify the text of the body shape.
bodyShape.TextBody = New TextBody(New Drawing.BodyProperties, New Drawing.ListStyle, New Drawing.Paragraph)
' Create the slide part for the new slide.
Dim slidePart As SlidePart = presentationPart.AddNewPart(Of SlidePart)()

' Save the new slide part.
slide.Save(slidePart)

' Modify the slide ID list in the presentation part.
' The slide ID list should not be null.
Dim slideIdList As SlideIdList = presentationPart.Presentation.SlideIdList

' Find the highest slide ID in the current list.
Dim maxSlideId As UInteger = 1
Dim prevSlideId As SlideId = Nothing

For Each slideId As SlideId In slideIdList.ChildElements
If (CType(slideId.Id, UInteger) > maxSlideId) Then
maxSlideId = slideId.Id
End If
position = (position - 1)
If (position = 0) Then
prevSlideId = slideId
End If
Next

maxSlideId = (maxSlideId + 1)

' Get the ID of the previous slide.
Dim lastSlidePart As SlidePart = Nothing

If (Not prevSlideId Is Nothing) Then
lastSlidePart = CType(presentationPart.GetPartById(prevSlideId.RelationshipId), SlidePart)
Else
lastSlidePart = CType(presentationPart.GetPartById(CType(slideIdList.ChildElements(0), SlideId).RelationshipId), SlidePart)
End If

' Use the same slide layout as that of the previous slide.
If (Not (lastSlidePart.SlideLayoutPart) Is Nothing) Then
slidePart.AddPart(lastSlidePart.SlideLayoutPart)
End If

' Insert the new slide into the slide list after the previous slide.
Dim newSlideId As SlideId = slideIdList.InsertAfter(New SlideId, prevSlideId)
newSlideId.Id = maxSlideId
newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart)

' Save the modified prsentation.
presentationPart.Presentation.Save()

End Sub

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Here is the code to delete a slide from a .pptx presentation.

Public Sub DeleteSlide(ByVal presentationFile As String, ByVal slideIndex As Integer)

' Open the source document as read/write.
Dim presentationDoc As PresentationDocument = PresentationDocument.Open(presentationFile, True)

Using (presentationDoc)

' Pass the source document and the index of the slide to be deleted to the next DeleteSlide method.
DeleteSlide(presentationDoc, slideIndex)

End Using

End Sub

Private Sub DeleteSlide(ByVal presentationDocument As PresentationDocument, ByVal slideIndex As Integer)
If (presentationDocument Is Nothing) Then
Throw New ArgumentNullException("presentationDocument")
End If

' Use the CountSlides code example to get the number of slides in the presentation.
Dim slidesCount As Integer = presentationDocument.PresentationPart.Presentation.SlideIdList.ChildElements.Count 'presentationDocument.CountSlides(presentationDocument)
If ((slideIndex < 0) OrElse (slideIndex >= slidesCount)) Then
Throw New ArgumentOutOfRangeException("slideIndex")
End If

' Get the presentation part from the presentation document.
Dim presentationPart As PresentationPart = presentationDocument.PresentationPart

' Get the presentation from the presentation part.
Dim presentation As DocumentFormat.OpenXml.Presentation.Presentation = presentationPart.Presentation

' Get the list of slide IDs in the presentation.
Dim slideIdList As SlideIdList = presentation.SlideIdList

' Get the slide ID of the specified slide.
Dim slideId As SlideId = CType(slideIdList.ChildElements(slideIndex), SlideId)

' Get the relationship ID of the specified slide.
Dim slideRelId As String = slideId.RelationshipId

' Remove the slide from the slide list.
slideIdList.RemoveChild(slideId)

' Remove references to the slide from all custom shows.
If (Not (presentation.CustomShowList) Is Nothing) Then

' Iterate through the list of custom shows.
For Each customShow As System.Object In presentation.CustomShowList.Elements(Of _
DocumentFormat.OpenXml.Presentation.CustomShow)()

If (Not (customShow.SlideList) Is Nothing) Then

' Declare a linked list.
Dim slideListEntries As LinkedList(Of SlideListEntry) = New LinkedList(Of SlideListEntry)

' Iterate through all the slides in the custom show.
For Each slideListEntry As SlideListEntry In customShow.SlideList.Elements

' Find the slide reference to be removed from the custom show.
If ((Not (slideListEntry.Id) Is Nothing) _
AndAlso (slideListEntry.Id = slideRelId)) Then

' Add that slide reference to the end of the linked list.
slideListEntries.AddLast(slideListEntry)
End If
Next

' Remove references to the slide from the custom show.
For Each slideListEntry As SlideListEntry In slideListEntries
customShow.SlideList.RemoveChild(slideListEntry)
Next
End If
Next
End If

' Save the change to the presentation part.
presentation.Save()

' Get the slide part for the specified slide.
Dim slidePart As SlidePart = CType(presentationPart.GetPartById(slideRelId), SlidePart)

' Remove the slide part.
presentationPart.DeletePart(slidePart)

End Sub

120-overwatch_max50

30 posts

back to top
Rate

Rate This | Posted 7 months ago

 

Anyone that is interested on learning more about this topic or has some insight into this topic please sign up for my new group "Office Open XML Development".


Thanks


James