2011-04-26 193 views
6

我使用的是this代碼的修改版本來創建Excel文檔,添加單元格和樣式單元格。我正在嘗試修改此代碼,以便能夠將圖像添加到工作表。我無處可去,網絡上真的沒有任何東西可以提供幫助。我正在嘗試通讀OpenXML生產力工具diff。這是無益的。任何人都可以指出我的方向嗎?C#&OpenXML:將圖像插入到Excel文檔中

謝謝。

回答

0

我看着從陳志遠和大衛·葉茨的答案。由於需要幾小時的編碼才能滿足以下簡單要求,我將在此發佈我的解決方案,以便下一個人可以節省一些時間。

要求:

  • 的圖像添加到現有的Excel電子表格/片材的特定小區
  • 創建一個新的電子表格和圖像添加到特定的細胞
  • 的圖像添加到一個WorksheetPart的特定單元格(所以其他操作可以在它保存之前執行)
  • 添加圖像流
  • 添加圖像從文件
  • 使用不同的圖像格式

用法

// Add via file to existing spreadsheet 
try 
{ 
    ExcelTools.AddImage(false, filePath, "Sheet name", 
         imagePath, "Image description", 
         2 /* column */, 2 /* row */); 
} 
catch ... 

// Add via stream to existing spreadsheet 
try 
{ 
    ExcelTools.AddImage(false, filePath, "Sheet name", 
         imageStream, "Image description", 
         2 /* column */, 2 /* row */); 
} 
catch ... 

// Create spreadsheet and add image via path 
try 
{ 
    ExcelTools.AddImage(true, filePath, "Sheet name", 
         imagePath, "Image description", 
         2 /* column */, 2 /* row */); 
} 
catch ... 

// Create spreadsheet and add image via stream 
try 
{ 
    ExcelTools.AddImage(true, filePath, "Sheet name", 
         imageStream, "Image description", 
         2 /* column */, 2 /* row */); 
} 
catch ... 

// Add multiple images or apply further changes 
try 
{ 
    // Open spreadsheet 
    spreadsheetDocument = SpreadsheetDocument.Open(excelFile, true); 

    // Get WorksheetPart 
    worksheetPart = ExcelTools.GetWorksheetPartByName(spreadsheetDocument, "Some sheet name"); 

    AddImage(worksheetPart, imagePath1, "My first image", 1, 1); // A1 
    AddImage(worksheetPart, imagePath2, "My second image", 1, 5); // A5 
    AddImage(worksheetPart, imagePath3, "My third image", 2, 7); // B7 

    // Other operations if needed 

    worksheetPart.Worksheet.Save(); 

    spreadsheetDocument.Close(); 
} 
catch ... 

代碼:

using System; 
using System.Data; 
using System.Linq; 
using System.IO; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Collections.Generic; 
using DocumentFormat.OpenXml; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Spreadsheet; 
using A = DocumentFormat.OpenXml.Drawing; 
using Xdr = DocumentFormat.OpenXml.Drawing.Spreadsheet; 

namespace Utilities 
{ 
    public class ExcelTools 
    { 
     public static ImagePartType GetImagePartTypeByBitmap(Bitmap image) 
     { 
      if (ImageFormat.Bmp.Equals(image.RawFormat)) 
       return ImagePartType.Bmp; 
      else if (ImageFormat.Gif.Equals(image.RawFormat)) 
       return ImagePartType.Gif; 
      else if (ImageFormat.Png.Equals(image.RawFormat)) 
       return ImagePartType.Png; 
      else if (ImageFormat.Tiff.Equals(image.RawFormat)) 
       return ImagePartType.Tiff; 
      else if (ImageFormat.Icon.Equals(image.RawFormat)) 
       return ImagePartType.Icon; 
      else if (ImageFormat.Jpeg.Equals(image.RawFormat)) 
       return ImagePartType.Jpeg; 
      else if (ImageFormat.Emf.Equals(image.RawFormat)) 
       return ImagePartType.Emf; 
      else if (ImageFormat.Wmf.Equals(image.RawFormat)) 
       return ImagePartType.Wmf; 
      else 
       throw new Exception("Image type could not be determined."); 
     } 

     public static WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName) 
     { 
      IEnumerable<Sheet> sheets = 
       document.WorkbookPart.Workbook.GetFirstChild<Sheets>(). 
       Elements<Sheet>().Where(s => s.Name == sheetName); 

      if (sheets.Count() == 0) 
      { 
       // The specified worksheet does not exist 
       return null; 
      } 

      string relationshipId = sheets.First().Id.Value; 
      return (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId); 
     } 

     public static void AddImage(bool createFile, string excelFile, string sheetName, 
            string imageFileName, string imgDesc, 
            int colNumber, int rowNumber) 
     { 
      using (var imageStream = new FileStream(imageFileName, FileMode.Open)) 
      { 
       AddImage(createFile, excelFile, sheetName, imageStream, imgDesc, colNumber, rowNumber); 
      } 
     } 

     public static void AddImage(WorksheetPart worksheetPart, 
            string imageFileName, string imgDesc, 
            int colNumber, int rowNumber) 
     { 
      using (var imageStream = new FileStream(imageFileName, FileMode.Open)) 
      { 
       AddImage(worksheetPart, imageStream, imgDesc, colNumber, rowNumber); 
      } 
     } 

     public static void AddImage(bool createFile, string excelFile, string sheetName, 
            Stream imageStream, string imgDesc, 
            int colNumber, int rowNumber) 
     { 
      SpreadsheetDocument spreadsheetDocument = null; 
      WorksheetPart worksheetPart = null; 
      if (createFile) 
      { 
       // Create a spreadsheet document by supplying the filepath 
       spreadsheetDocument = SpreadsheetDocument.Create(excelFile, SpreadsheetDocumentType.Workbook); 

       // Add a WorkbookPart to the document 
       WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart(); 
       workbookpart.Workbook = new Workbook(); 

       // Add a WorksheetPart to the WorkbookPart 
       worksheetPart = workbookpart.AddNewPart<WorksheetPart>(); 
       worksheetPart.Worksheet = new Worksheet(new SheetData()); 

       // Add Sheets to the Workbook 
       Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook. 
        AppendChild<Sheets>(new Sheets()); 

       // Append a new worksheet and associate it with the workbook 
       Sheet sheet = new Sheet() 
       { 
        Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), 
        SheetId = 1, 
        Name = sheetName 
       }; 
       sheets.Append(sheet); 
      } 
      else 
      { 
       // Open spreadsheet 
       spreadsheetDocument = SpreadsheetDocument.Open(excelFile, true); 

       // Get WorksheetPart 
       worksheetPart = GetWorksheetPartByName(spreadsheetDocument, sheetName); 
      } 

      AddImage(worksheetPart, imageStream, imgDesc, colNumber, rowNumber); 

      worksheetPart.Worksheet.Save(); 

      spreadsheetDocument.Close(); 
     } 

     public static void AddImage(WorksheetPart worksheetPart, 
            Stream imageStream, string imgDesc, 
            int colNumber, int rowNumber) 
     { 
      // We need the image stream more than once, thus we create a memory copy 
      MemoryStream imageMemStream = new MemoryStream(); 
      imageStream.Position = 0; 
      imageStream.CopyTo(imageMemStream); 
      imageStream.Position = 0; 

      var drawingsPart = worksheetPart.DrawingsPart; 
      if (drawingsPart == null) 
       drawingsPart = worksheetPart.AddNewPart<DrawingsPart>(); 

      if (!worksheetPart.Worksheet.ChildElements.OfType<Drawing>().Any()) 
      { 
       worksheetPart.Worksheet.Append(new Drawing { Id = worksheetPart.GetIdOfPart(drawingsPart) }); 
      } 

      if (drawingsPart.WorksheetDrawing == null) 
      { 
       drawingsPart.WorksheetDrawing = new Xdr.WorksheetDrawing(); 
      } 

      var worksheetDrawing = drawingsPart.WorksheetDrawing; 

      Bitmap bm = new Bitmap(imageMemStream); 
      var imagePart = drawingsPart.AddImagePart(GetImagePartTypeByBitmap(bm)); 
      imagePart.FeedData(imageStream); 

      A.Extents extents = new A.Extents(); 
      var extentsCx = bm.Width * (long)(914400/bm.HorizontalResolution); 
      var extentsCy = bm.Height * (long)(914400/bm.VerticalResolution); 
      bm.Dispose(); 

      var colOffset = 0; 
      var rowOffset = 0; 

      var nvps = worksheetDrawing.Descendants<Xdr.NonVisualDrawingProperties>(); 
      var nvpId = nvps.Count() > 0 
       ? (UInt32Value)worksheetDrawing.Descendants<Xdr.NonVisualDrawingProperties>().Max(p => p.Id.Value) + 1 
       : 1U; 

      var oneCellAnchor = new Xdr.OneCellAnchor(
       new Xdr.FromMarker 
       { 
        ColumnId = new Xdr.ColumnId((colNumber - 1).ToString()), 
        RowId = new Xdr.RowId((rowNumber - 1).ToString()), 
        ColumnOffset = new Xdr.ColumnOffset(colOffset.ToString()), 
        RowOffset = new Xdr.RowOffset(rowOffset.ToString()) 
       }, 
       new Xdr.Extent { Cx = extentsCx, Cy = extentsCy }, 
       new Xdr.Picture(
        new Xdr.NonVisualPictureProperties(
         new Xdr.NonVisualDrawingProperties { Id = nvpId, Name = "Picture " + nvpId, Description = imgDesc }, 
         new Xdr.NonVisualPictureDrawingProperties(new A.PictureLocks { NoChangeAspect = true }) 
        ), 
        new Xdr.BlipFill(
         new A.Blip { Embed = drawingsPart.GetIdOfPart(imagePart), CompressionState = A.BlipCompressionValues.Print }, 
         new A.Stretch(new A.FillRectangle()) 
        ), 
        new Xdr.ShapeProperties(
         new A.Transform2D(
          new A.Offset { X = 0, Y = 0 }, 
          new A.Extents { Cx = extentsCx, Cy = extentsCy } 
         ), 
         new A.PresetGeometry { Preset = A.ShapeTypeValues.Rectangle } 
        ) 
       ), 
       new Xdr.ClientData() 
      ); 

      worksheetDrawing.Append(oneCellAnchor); 
     } 
    } 
}