开发者

How do you copy an Excel worksheet into a new workbook AND bring all the charts, images, etc.?

Our application has distribution functionality. It takes several Excel 2007 spreadsheets, copies them into a single sheet, then emails them to the users. The problem is that images and charts are not copying over. I have tried everything I can find on here and various other sources, but sadly nothing seems to work. Our application is written using VSTO, and I have also tried OpenXML, but nothing seems to work. In fact trying to copy over in OpenXML corrupted the files so badly that Excel could not read or recover them. Here's the code we use (note: we have ExcelWrapper simply calls the same functions on the Excel App but hides all the optional items).

 private void CreateWorkbook(string filePath, string batchReportsPath)
    {
        //place the xlsx file into a workbook.
        //call getfilesnames

        Excel.Workbook bookToCopy;
        Excel.Workbook newWorkbook;
        Excel.Worksheet tempSheet = new Excel.Worksheet();

        newWorkbook = ExcelWrapper.WorkbooksAdd(ExcelApp.Workbooks);

        if (File.Exists(filePath))
            File.Delete(filePath);

        ExcelWrapper.WorkbookSaveAs(newWorkbook, filePath);

        List<string> filePaths = new List<string>(Directory.GetFiles(batchReportsPath));
        filePaths.ForEach(delegate(string reportPath)
        {
            string reportPathAndName = reportPath;

            bookToCopy = ExcelWrapper.WorkbooksOpen(ExcelApp.Workbooks, reportPathAndName);

            int nextSheetNumber = newWorkbook.Sheets.Count;
            ((Excel.Worksheet)sheetToSend.Sheets[1]).Copy(Type.Missing, newWorkbook.Sheets[nextSheetNumber]);


            ExcelWrapper.WorkbookClose(bookToCopy);
        });


        newWorkbook.Save();
        ExcelWrapper.WorkbookClose(newWorkbook);
        bookToCopy= null;
        tempSheet = null;
        newWorkbook = null;

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }

I have tried every promising option and searched both the VSTO and OpenXML object models and I am stumped. Please stackoverflow community, you're my only hope.

UPDATE: Here's the answer folks:

 //Copy all the images, Charts, shapes
   foreach (Ex开发者_如何转开发cel.Shape o in copySheet.Shapes)
   {
         if (o.Type == Microsoft.Office.Core.MsoShapeType.msoPicture)
             o.CopyPicture();
         else
             o.Copy();

         newWorkbook.Save();
   }

You need to do the save after each copy to get the Paste to finalize. Thanks for your input.


You'll need to check the WORKSHEET object of the worksheet you're looking to copy, then run through all the "*Objects" properties, and, for each of those collections, write code to manually copy all the elements in that collection to the new sheet.

For example, you've got:

ChartObjects ListObjects OleObjects Shapes (Which might get copied along with the sheet, I'm not sure).


Perhaps you can get there by a copy/paste? Here's an example that copies cell data, charts and images: MSDN

Good luck!


I don't have an answer but I can give you some pointers. First, this is not an openxml question, it's a vsto question. Second, images and charts are attached to a spreadsheet, they are not content in it (a subtle distinction). There is probably a property of all charts and one of all images attached to the sheet. Copy that across.

(I use the IExtensibility interface instead of VSTO so I know what's in the underlying API, but not the property names - sorry.)


This is how I do it -- moves the entire worksheet from source workbook to a brand new workbook:

public static void MoveWorksheet()
{
public static Excel.Application oXL;
public static Excel._Worksheet ws;
if (File.Exists(Global.Variables.GlobalVariables.recap))
{
//workbookToOpen is location and name
oXL.Workbooks.Open(workbookToOpen, Missing.Value, true);
object ws = null;
try
{
    ws = wb.Sheets["Sheet 1"];
    if (ws != null)
    {
        ((Worksheet)ws).UsedRange.Interior.ColorIndex = Constants.xlNone;
        ((Worksheet)ws).Copy();
        oXL.ActiveWorkbook.SaveAs("SaveAsFileName" + ".xlsx");
        oXL.ActiveWorkbook.Close(true);
    }
}
catch {}
}
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜