Hi
I have a solution of creating and merging Excel-files in a webservice.
This has been working fine, until both of the Excel-files began to contain images.
As an example, the service recieves one Excel template and one Excel workbook.
The goal is to create a new Excel workbook consisting of the supplied parts.
Since the template is indeed a template (xltx), I start of by working with the workbook.
I then merge all worksheets from the template file to the workbook file.
This is done in memory with the help of
EPPlus version 3.1.2 and the following routine where grmName is path to the template file and wbkName is path to the workbook:
Friend Sub XLAddInfoSheets(ByVal grmName As String, ByVal wbkName As String) Dim targetFI As New FileInfo(wbkName) Dim templateFile As String = grmName Dim ContentOverrides As New ArrayList Try Using t As New ExcelPackage Using Tstream As New FileStream(wbkName, FileMode.Open, FileAccess.ReadWrite) t.Load(Tstream) End Using Using d As New ExcelPackage Using Dstream As New FileStream(templateFile, FileMode.Open) d.Load(Dstream) End Using For Each dws In d.Workbook.Worksheets Dim addOK As Boolean = True If dws.Name = "Försättsblad" Or dws.Name = "Cover Page" Then Dim tmpName As String = dws.Name For Each twx In t.Workbook.Worksheets If LCase(twx.Name) = LCase(tmpName) Then addOK = False Exit For End If Next If addOK Then t.Workbook.Worksheets.Add(tmpName, dws) t.Workbook.Worksheets(tmpName).Hidden = dws.Hidden End If End If Next End Using t.SaveAs(targetFI) End Using Catch ex As Exception WriteLogg("Could not merge coverpages from the template.", ex.Message, logFile) Exit Sub End Try End Sub
When opening the created file (if both the template and the workbook contains images) shows a repairable error.
After the repair is made, the images in the inserted sheets is actually an image from the original workbook, not the same image as in the template sheet.
I realise that there is a mixup of relations causing this, so I tried looping through the images in the inserted sheets and delete the original image (DrawingPart) and add the image again.
This is done with the following code where wbPart is the actual Workbookpart and imagePath is path to the image which is extracted to disk earlier:
Private Sub XLRelateImages(ByVal wbPart As WorksheetPart, ByVal imagePath As String) Try Dim drawingPart = wbPart.DrawingsPart If drawingPart IsNot Nothing Then Dim doc As New XmlDocument() doc.Load(drawingPart.GetStream()) Dim ns As New XmlNamespaceManager(doc.NameTable) ns.AddNamespace("a", "http://schemas.openxmlformats.org/drawingml/2006/main") ns.AddNamespace("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing") Dim list As XmlNodeList = doc.SelectNodes("/xdr:wsDr/xdr:twoCellAnchor/xdr:pic/xdr:blipFill/a:blip", ns) Dim pairList As New List(Of KeyValuePair(Of String, String))() For Each node As XmlNode In list For Each attribute As XmlAttribute In node.Attributes Dim pair As New KeyValuePair(Of String, String)(attribute.Value, attribute.Name) pairList.Add(pair) Next Next For Each image As KeyValuePair(Of String, String) In pairList Dim id As String = image.Key Dim name As String = image.Value Dim oldPart As OpenXmlPart = Nothing If name = "r:embed" Then ' get ImagePart via id oldPart = drawingPart.GetPartById(id) ' delete ImagePart drawingPart.DeletePart(oldPart) ' add the ImagePart Dim newPart As ImagePart = drawingPart.AddImagePart(ImagePartType.Png, id) ' replace image Dim replacement As String = imagePath Using stream As New FileStream(replacement, FileMode.Open) ' feed data to the newPart newPart.FeedData(stream) End Using End If Next ' save xml document to the stream doc.Save(drawingPart.GetStream(FileMode.Create)) End If Catch ex As Exception End Try End Sub
When I examine the result of this I still get the same error when I'm opening the file, but the correct image is now shown on the inserted sheets.
I believe there must be some other relation that is left in the workbook, but I have not been able to locate it.
Can someone help with sample code in VB or C# I would be much obliged?
Best Regards Peter Karlström Midrange AB, Sweden