private ZipPackageRelationship CreateThemeOverridePart(ZipPackage p, ZipPackagePart partToCopy) { var id = GetIxFromChartUri(_chart.UriChart.OriginalString); ThemeOverrideUri = GetNewUri(p, "/xl/theme/themeOverride{0}.xml", ref id); var rel = _chart.Part.CreateRelationship(ThemeOverrideUri, TargetMode.Internal, ExcelPackage.schemaThemeOverrideRelationships); ThemeOverridePart = p.CreatePart(ThemeOverrideUri, ExcelPackage.contentTypeThemeOverride); ThemeOverrideXml = new XmlDocument(); ThemeOverrideXml.Load(partToCopy.GetStream()); foreach (var themeRel in partToCopy.GetRelationships()) { var uri = OfficeOpenXml.Utils.UriHelper.ResolvePartUri(themeRel.SourceUri, themeRel.TargetUri); var toPart = _chart.Part.Package.CreatePart(uri, PictureStore.GetContentType(uri.OriginalString)); var imageRel = ThemeOverridePart.CreateRelationship(uri, TargetMode.Internal, themeRel.RelationshipType); SetRelIdInThemeDoc(ThemeOverrideXml, themeRel.Id, imageRel.Id); var stream = partToCopy.GetStream(); var b = stream.GetBuffer(); toPart.GetStream().Write(b, 0, b.Length); } ThemeOverrideXml.Save(ThemeOverridePart.GetStream(FileMode.CreateNew)); partToCopy.Package.Dispose(); return(rel); }
/// <summary> /// Inserts a picture at the end of the text in the header or footer /// </summary> /// <param name="PictureFile">The image object containing the Picture</param> /// <param name="Alignment">Alignment. The image object will be inserted at the end of the Text.</param> public ExcelVmlDrawingPicture InsertPicture(FileInfo PictureFile, PictureAlignment Alignment) { string id = ValidateImage(Alignment); Image Picture; try { if (!PictureFile.Exists) { throw (new FileNotFoundException(string.Format("{0} is missing", PictureFile.FullName))); } Picture = Image.FromFile(PictureFile.FullName); } catch (Exception ex) { throw (new InvalidDataException("File is not a supported image-file or is corrupt", ex)); } string contentType = PictureStore.GetContentType(PictureFile.Extension); var uriPic = XmlHelper.GetNewUri(_ws._package.ZipPackage, "/xl/media/" + PictureFile.Name.Substring(0, PictureFile.Name.Length - PictureFile.Extension.Length) + "{0}" + PictureFile.Extension); #if (Core) var imgBytes = ImageCompat.GetImageAsByteArray(Picture); #else var ic = new ImageConverter(); byte[] imgBytes = (byte[])ic.ConvertTo(Picture, typeof(byte[])); #endif var ii = _ws.Workbook._package.PictureStore.AddImage(imgBytes, uriPic, contentType); return(AddImage(Picture, id, ii)); }
internal void AddImage(FileInfo file) { if (!file.Exists) { throw (new ArgumentException($"File {file.FullName} does not exist.")); } ContentType = PictureStore.GetContentType(file.Extension); var image = Image.FromFile(file.FullName); AddImage(image); }
internal void SaveImage() { if (_image != null) { try { string relId = PictureStore.SavePicture(_image, this); //Create relationship SetXmlNodeString("v:fill/@o:relid", relId); } catch (Exception ex) { throw (new Exception("Can't save image - " + ex.Message, ex)); } } }
internal override void GetXml() { var relId = _xml.GetXmlNodeString("a:blip/@r:embed"); if (!string.IsNullOrEmpty(relId)) { _image = PictureStore.GetPicture(relId, this, out string contentType); ContentType = contentType; } SourceRectangle = new ExcelDrawingRectangle(_xml, "a:srcRect/", 0); Stretch = _xml.ExistNode("a:stretch"); if (Stretch) { StretchOffset = new ExcelDrawingRectangle(_xml, "a:stretch/a:fillRect/", 0); } Tile = new ExcelDrawingBlipFillTile(_xml); }
/// <summary> /// Set the picture from an image file. /// The image file will be saved as a blob, so make sure Excel supports the image format. /// </summary> /// <param name="PictureFile">The image file.</param> public void SetFromFile(FileInfo PictureFile) { DeletePrevImage(); Image img; byte[] fileBytes; try { fileBytes = File.ReadAllBytes(PictureFile.FullName); img = Image.FromFile(PictureFile.FullName); } catch (Exception ex) { throw (new InvalidDataException("File is not a supported image-file or is corrupt", ex)); } string contentType = PictureStore.GetContentType(PictureFile.Extension); var imageURI = XmlHelper.GetNewUri(_workSheet._package.ZipPackage, "/xl/media/" + PictureFile.Name.Substring(0, PictureFile.Name.Length - PictureFile.Extension.Length) + "{0}" + PictureFile.Extension); var ii = _workSheet.Workbook._package.PictureStore.AddImage(fileBytes, imageURI, contentType); if (_workSheet.Part.Package.PartExists(imageURI) && ii.RefCount == 1) //The file exists with another content, overwrite it. { //Remove the part if it exists _workSheet.Part.Package.DeletePart(imageURI); } var imagePart = _workSheet.Part.Package.CreatePart(imageURI, contentType, CompressionLevel.None); //Save the picture to package. var strm = imagePart.GetStream(FileMode.Create, FileAccess.Write); strm.Write(fileBytes, 0, fileBytes.Length); var rel = _workSheet.Part.CreateRelationship(imageURI, Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image"); SetXmlNodeString(BACKGROUNDPIC_PATH, rel.Id); }
private static void CopyDrawing(ExcelPackage pck, XmlNamespaceManager nsm, ExcelWorksheet Copy, ExcelWorksheet added) { //First copy the drawing XML string xml = Copy.Drawings.DrawingXml.OuterXml; var uriDraw = new Uri(string.Format("/xl/drawings/drawing{0}.xml", added.SheetId), UriKind.Relative); var part = pck.ZipPackage.CreatePart(uriDraw, "application/vnd.openxmlformats-officedocument.drawing+xml", pck.Compression); StreamWriter streamDrawing = new StreamWriter(part.GetStream(FileMode.Create, FileAccess.Write)); streamDrawing.Write(xml); streamDrawing.Flush(); XmlDocument drawXml = new XmlDocument(); drawXml.LoadXml(xml); //Add the relationship ID to the worksheet xml. var drawRelation = added.Part.CreateRelationship(UriHelper.GetRelativeUri(added.WorksheetUri, uriDraw), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/drawing"); XmlElement e = added.WorksheetXml.SelectSingleNode("//d:drawing", nsm) as XmlElement; e.SetAttribute("id", ExcelPackage.schemaRelationships, drawRelation.Id); for (int i = 0; i < Copy.Drawings.Count; i++) { ExcelDrawing draw = Copy.Drawings[i]; //draw.AdjustPositionAndSize(); //Adjust position for any change in normal style font/row size etc. if (draw is ExcelChart chart) { xml = chart.ChartXml.InnerXml; var UriChart = XmlHelper.GetNewUri(pck.ZipPackage, "/xl/charts/chart{0}.xml"); var chartPart = pck.ZipPackage.CreatePart(UriChart, ContentTypes.contentTypeChart, pck.Compression); StreamWriter streamChart = new StreamWriter(chartPart.GetStream(FileMode.Create, FileAccess.Write)); streamChart.Write(xml); streamChart.Flush(); //Now create the new relationship to the copied chart xml var prevRelID = draw.TopNode.SelectSingleNode("xdr:graphicFrame/a:graphic/a:graphicData/c:chart/@r:id", Copy.Drawings.NameSpaceManager).Value; var rel = part.CreateRelationship(UriHelper.GetRelativeUri(uriDraw, UriChart), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/chart"); XmlAttribute relAtt = drawXml.SelectSingleNode(string.Format("//c:chart/@r:id[.='{0}']", prevRelID), Copy.Drawings.NameSpaceManager) as XmlAttribute; relAtt.Value = rel.Id; } else if (draw is ExcelPicture pic) { IPictureContainer container = pic; var uri = container.UriPic; var img = PictureStore.ImageToByteArray(pic.Image); var ii = added.Workbook._package.PictureStore.AddImage(img, null, pic.ContentType); var rel = part.CreateRelationship(UriHelper.GetRelativeUri(added.WorksheetUri, ii.Uri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image"); //Fixes problem with invalid image when the same image is used more than once. XmlNode relAtt = drawXml.SelectSingleNode( string.Format( "//xdr:pic/xdr:nvPicPr/xdr:cNvPr/@name[.='{0}']/../../../xdr:blipFill/a:blip/@r:embed", pic.Name), Copy.Drawings.NameSpaceManager); if (relAtt != null) { relAtt.Value = rel.Id; } } else if (draw is ExcelTableSlicer slicer) { var name = pck.Workbook.GetSlicerName(slicer.Name); var newSlicer = added.Drawings[i] as ExcelTableSlicer; newSlicer.Name = name; newSlicer.SlicerName = name; //The slicer still reference the copied slicers cache. We need to create a new cache for the copied slicer. newSlicer.CreateNewCache(); } else if (draw is ExcelPivotTableSlicer ptSlicer) { var name = pck.Workbook.GetSlicerName(ptSlicer.Name); var newSlicer = added.Drawings[i] as ExcelPivotTableSlicer; newSlicer.Name = name; newSlicer.SlicerName = name; //The slicer still reference the copied slicers cache. We need to create a new cache for the copied slicer. newSlicer.CreateNewCache(ptSlicer.Cache._field); } else if (draw is ExcelControl ctrl) { var UriCtrl = XmlHelper.GetNewUri(pck.ZipPackage, "/xl/ctrlProps/ctrlProp{0}.xml"); var ctrlPart = pck.ZipPackage.CreatePart(UriCtrl, ContentTypes.contentTypeControlProperties, pck.Compression); StreamWriter streamChart = new StreamWriter(ctrlPart.GetStream(FileMode.Create, FileAccess.Write)); streamChart.Write(ctrl.ControlPropertiesXml.OuterXml); streamChart.Flush(); var prevRelID = ctrl._control.RelationshipId; var rel = added.Part.CreateRelationship(UriHelper.GetRelativeUri(added.WorksheetUri, UriCtrl), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/ctrlProp"); XmlAttribute relAtt = added.WorksheetXml.SelectSingleNode(string.Format("//d:control/@r:id[.='{0}']", prevRelID), added.NameSpaceManager) as XmlAttribute; relAtt.Value = rel.Id; } } //rewrite the drawing xml with the new relID's streamDrawing = new StreamWriter(part.GetStream(FileMode.Create, FileAccess.Write)); streamDrawing.Write(drawXml.OuterXml); streamDrawing.Flush(); //Copy the size variables to the copy. for (int i = 0; i < Copy.Drawings.Count; i++) { var draw = Copy.Drawings[i]; var c = added.Drawings[i]; if (c != null) { c._left = draw._left; c._top = draw._top; c._height = draw._height; c._width = draw._width; } if (c is ExcelChart chart) { for (int j = 0; i < chart.Series.Count; i++) { var s = chart.Series[j]; var a = new ExcelAddressBase(s.Series); if (a.WorkSheetName.Equals(Copy.Name)) { s.Series = ExcelAddressBase.GetFullAddress(added.Name, a.LocalAddress); } a = new ExcelAddressBase(s.XSeries); if (a.WorkSheetName.Equals(Copy.Name)) { s.XSeries = ExcelAddressBase.GetFullAddress(added.Name, a.LocalAddress); } } } } }