Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloning sheet doesn't clone Drawing part #1787

Open
SzymonSel opened this issue Sep 9, 2024 · 0 comments
Open

Cloning sheet doesn't clone Drawing part #1787

SzymonSel opened this issue Sep 9, 2024 · 0 comments

Comments

@SzymonSel
Copy link

Describe the bug
I have a template xlsx file, with template sheet, which in turn are cloned and their content is replaced ie. Cell values and images.
After opening the file, the cell values are unique for each cloned Sheet except for the images which are the same, namely the last replaced image.

Screenshots
image

To Reproduce
I have this code which clones a given Sheet:

    public static async void CloneSheet(SpreadsheetDocument spreadSheet, string sheetName, string newSheetName) {
          // Get the source sheet
          var sheets = spreadSheet.WorkbookPart.Workbook.Sheets;
          var sourceSheet = sheets.Elements<Sheet>().FirstOrDefault(s => s.Name == sheetName);
          if (sourceSheet == null) {
              throw new ArgumentException($"Sheet with name {sheetName} does not exist.");
          }

          // Get the source worksheet part
          var sourceSheetPart = (WorksheetPart)spreadSheet.WorkbookPart.GetPartById(sourceSheet.Id);

          // Create a new worksheet part
          var newSheetPart = spreadSheet.WorkbookPart.AddNewPart<WorksheetPart>();
          newSheetPart.Worksheet = (Worksheet)sourceSheetPart.Worksheet.Clone();

          // Clone the relationships
          foreach (var rel in sourceSheetPart.Parts) {
              newSheetPart.AddPart(rel.OpenXmlPart, rel.RelationshipId);
          }

          // Clone DrawingsPart and its related ImageParts
          if (sourceSheetPart.DrawingsPart != null) {
              var sourceDrawingsPart = sourceSheetPart.DrawingsPart;
              DrawingsPart newDrawingsPart;
              
              if (newSheetPart.DrawingsPart == null) {
                  newDrawingsPart = newSheetPart.AddNewPart<DrawingsPart>();
              } else {
                  newDrawingsPart = newSheetPart.DrawingsPart;
              }

              newDrawingsPart.WorksheetDrawing = (WorksheetDrawing)sourceDrawingsPart.WorksheetDrawing.Clone();

              var imagePartsToClone = sourceDrawingsPart.ImageParts.ToList();

              foreach (var imagePart in imagePartsToClone) {
                  var newImagePart = newDrawingsPart.AddImagePart(imagePart.ContentType);


                  using (var stream = imagePart.GetStream()) {
                          newImagePart.FeedData(stream);
                  }

                  // Update the BlipFill.Blip.Embed.Value to reference the new image part
                  foreach (var blip in newDrawingsPart.WorksheetDrawing.Descendants<DocumentFormat.OpenXml.Drawing.Blip>()) {
                      if (blip.Embed.Value == sourceDrawingsPart.GetIdOfPart(imagePart)) {
                          var newId = newDrawingsPart.GetIdOfPart(newImagePart);
                          blip.Embed.Value = newId;
                      }
                  }
              }
          }

          // Create a new sheet and add it to the workbook
          var newSheetId = spreadSheet.WorkbookPart.GetIdOfPart(newSheetPart);
          var newSheet = new Sheet {
              Id = newSheetId,
              SheetId = sheets.Elements<Sheet>().Max(s => s.SheetId.Value) + 1,
              Name = newSheetName // todo: Ensure the new sheet name is unique
          };

          sheets.Append(newSheet);

          // Save the workbook
          spreadSheet.WorkbookPart.Workbook.Save();
      }

Observed behavior
What I discovered is that the Clone() method on the sourceDrawingsPart.WorksheetDrawing doesn't work and in effect, make all the cloned sheets share the DrawingsPart.

Expected behavior
How can achieve DrawingsPart cloning to work?

Desktop (please complete the following information):

  • OS: MacOS, Windows
  • .NET Target: .NET Core, .NET Framework
  • DocumentFormat.OpenXml Version: 3.1.0, 3.0.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant