2017-02-09 37 views
0

以下は2つの方法です。一方はMemoryStreamを使用し、もう一方はディスク上の実ファイルを使用します。MemoryStreamを使用して画像をExcelに挿入する方法は?

 public void InsertImage(long x, long y, long? width, long? height, string sImagePath, WorksheetPart wsp) 
    { 
     try 
     { 
      DrawingsPart dp; 
      ImagePart imgp; 
      WorksheetDrawing wsd; 

      ImagePartType ipt; 
      switch (sImagePath.Substring(sImagePath.LastIndexOf('.') + 1).ToLower()) 
      { 
       case "png": 
        ipt = ImagePartType.Png; 
        break; 
       case "jpg": 
       case "jpeg": 
        ipt = ImagePartType.Jpeg; 
        break; 
       case "gif": 
        ipt = ImagePartType.Gif; 
        break; 
       default: 
        return; 
      } 

      if (wsp.DrawingsPart == null) 
      { 
       //----- no drawing part exists, add a new one 

       dp = wsp.AddNewPart<DrawingsPart>(); 
       imgp = dp.AddImagePart(ipt, wsp.GetIdOfPart(dp)); 
       wsd = new WorksheetDrawing(); 
      } 
      else 
      { 
       //----- use existing drawing part 

       dp = wsp.DrawingsPart; 
       imgp = dp.AddImagePart(ipt); 
       dp.CreateRelationshipToPart(imgp); 
       wsd = dp.WorksheetDrawing; 
      } 

      using (FileStream fs = new FileStream(sImagePath, FileMode.Open)) 
      { 
       imgp.FeedData(fs); 
      } 

      int imageNumber = dp.ImageParts.Count<ImagePart>(); 
      if (imageNumber == 1) 
      { 
       Drawing drawing = new Drawing(); 
       drawing.Id = dp.GetIdOfPart(imgp); 
       wsp.Worksheet.Append(drawing); 
      } 

      NonVisualDrawingProperties nvdp = new NonVisualDrawingProperties(); 
      nvdp.Id = new UInt32Value((uint)(1024 + imageNumber)); 
      nvdp.Name = "Picture " + imageNumber.ToString(); 
      nvdp.Description = ""; 
      DocumentFormat.OpenXml.Drawing.PictureLocks picLocks = new DocumentFormat.OpenXml.Drawing.PictureLocks(); 
      picLocks.NoChangeAspect = true; 
      picLocks.NoChangeArrowheads = true; 
      NonVisualPictureDrawingProperties nvpdp = new NonVisualPictureDrawingProperties(); 
      nvpdp.PictureLocks = picLocks; 
      NonVisualPictureProperties nvpp = new NonVisualPictureProperties(); 
      nvpp.NonVisualDrawingProperties = nvdp; 
      nvpp.NonVisualPictureDrawingProperties = nvpdp; 

      DocumentFormat.OpenXml.Drawing.Stretch stretch = new DocumentFormat.OpenXml.Drawing.Stretch(); 
      stretch.FillRectangle = new DocumentFormat.OpenXml.Drawing.FillRectangle(); 

      BlipFill blipFill = new BlipFill(); 
      DocumentFormat.OpenXml.Drawing.Blip blip = new DocumentFormat.OpenXml.Drawing.Blip(); 
      blip.Embed = dp.GetIdOfPart(imgp); 
      blip.CompressionState = DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print; 
      blipFill.Blip = blip; 
      blipFill.SourceRectangle = new DocumentFormat.OpenXml.Drawing.SourceRectangle(); 
      blipFill.Append(stretch); 

      DocumentFormat.OpenXml.Drawing.Transform2D t2d = new DocumentFormat.OpenXml.Drawing.Transform2D(); 
      DocumentFormat.OpenXml.Drawing.Offset offset = new DocumentFormat.OpenXml.Drawing.Offset(); 
      offset.X = 0; 
      offset.Y = 0; 
      t2d.Offset = offset; 
      Bitmap bm = new Bitmap(sImagePath); 

      DocumentFormat.OpenXml.Drawing.Extents extents = new DocumentFormat.OpenXml.Drawing.Extents(); 

      if (width == null) 
       extents.Cx = (long)bm.Width * (long)((float)914400/bm.HorizontalResolution); 
      else 
       extents.Cx = width * (long)((float)914400/bm.HorizontalResolution); 

      if (height == null) 
       extents.Cy = (long)bm.Height * (long)((float)914400/bm.VerticalResolution); 
      else 
       extents.Cy = height * (long)((float)914400/bm.VerticalResolution); 

      bm.Dispose(); 
      t2d.Extents = extents; 
      ShapeProperties sp = new ShapeProperties(); 
      sp.BlackWhiteMode = DocumentFormat.OpenXml.Drawing.BlackWhiteModeValues.Auto; 
      sp.Transform2D = t2d; 
      DocumentFormat.OpenXml.Drawing.PresetGeometry prstGeom = new DocumentFormat.OpenXml.Drawing.PresetGeometry(); 
      prstGeom.Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle; 
      prstGeom.AdjustValueList = new DocumentFormat.OpenXml.Drawing.AdjustValueList(); 
      sp.Append(prstGeom); 
      sp.Append(new DocumentFormat.OpenXml.Drawing.NoFill()); 

      DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture picture = new DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture(); 
      picture.NonVisualPictureProperties = nvpp; 
      picture.BlipFill = blipFill; 
      picture.ShapeProperties = sp; 

      Position pos = new Position(); 
      pos.X = x * 914400/72; 
      pos.Y = y * 914400/72; 
      Extent ext = new Extent(); 
      ext.Cx = extents.Cx; 
      ext.Cy = extents.Cy; 
      AbsoluteAnchor anchor = new AbsoluteAnchor(); 
      anchor.Position = pos; 
      anchor.Extent = ext; 
      anchor.Append(picture); 
      anchor.Append(new ClientData()); 
      wsd.Append(anchor); 
      wsd.Save(dp); 
     } 
     catch (Exception ex) 
     { 
      throw ex; // or do something more interesting if you want 
     } 
    } 

    //use memorystream 
public void InsertImage(long x, long y, long? width, long? height, MemoryStream ms, WorksheetPart wsp) 
     { 
      try 
      { 
       DrawingsPart dp; 
       ImagePart imgp; 
      WorksheetDrawing wsd; 

      ImagePartType ipt = ImagePartType.Jpeg; 

      if (wsp.DrawingsPart == null) 
      { 
       //----- no drawing part exists, add a new one 

       dp = wsp.AddNewPart<DrawingsPart>(); 
       imgp = dp.AddImagePart(ipt, wsp.GetIdOfPart(dp)); 
       wsd = new WorksheetDrawing(); 
      } 
      else 
      { 
       //----- use existing drawing part 

       dp = wsp.DrawingsPart; 
       imgp = dp.AddImagePart(ipt); 
       dp.CreateRelationshipToPart(imgp); 
       wsd = dp.WorksheetDrawing; 
      } 
      Bitmap bitmap = new Bitmap(ms); 
      imgp.FeedData(ms); 

      int imageNumber = dp.ImageParts.Count<ImagePart>(); 
      if (imageNumber == 1) 
      { 
       Drawing drawing = new Drawing(); 
       drawing.Id = dp.GetIdOfPart(imgp); 
       wsp.Worksheet.Append(drawing); 
      } 

      NonVisualDrawingProperties nvdp = new NonVisualDrawingProperties(); 
      nvdp.Id = new UInt32Value((uint)(1024 + imageNumber)); 
      nvdp.Name = "Picture " + imageNumber.ToString(); 
      nvdp.Description = ""; 
      DocumentFormat.OpenXml.Drawing.PictureLocks picLocks = new DocumentFormat.OpenXml.Drawing.PictureLocks(); 
      picLocks.NoChangeAspect = true; 
      picLocks.NoChangeArrowheads = true; 
      NonVisualPictureDrawingProperties nvpdp = new NonVisualPictureDrawingProperties(); 
      nvpdp.PictureLocks = picLocks; 
      NonVisualPictureProperties nvpp = new NonVisualPictureProperties(); 
      nvpp.NonVisualDrawingProperties = nvdp; 
      nvpp.NonVisualPictureDrawingProperties = nvpdp; 

      DocumentFormat.OpenXml.Drawing.Stretch stretch = new DocumentFormat.OpenXml.Drawing.Stretch(); 
      stretch.FillRectangle = new DocumentFormat.OpenXml.Drawing.FillRectangle(); 

      BlipFill blipFill = new BlipFill(); 
      DocumentFormat.OpenXml.Drawing.Blip blip = new DocumentFormat.OpenXml.Drawing.Blip(); 
      blip.Embed = dp.GetIdOfPart(imgp); 
      blip.CompressionState = DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print; 
      blipFill.Blip = blip; 
      blipFill.SourceRectangle = new DocumentFormat.OpenXml.Drawing.SourceRectangle(); 
      blipFill.Append(stretch); 

      DocumentFormat.OpenXml.Drawing.Transform2D t2d = new DocumentFormat.OpenXml.Drawing.Transform2D(); 
      DocumentFormat.OpenXml.Drawing.Offset offset = new DocumentFormat.OpenXml.Drawing.Offset(); 
      offset.X = 0; 
      offset.Y = 0; 
      t2d.Offset = offset; 


      DocumentFormat.OpenXml.Drawing.Extents extents = new DocumentFormat.OpenXml.Drawing.Extents(); 
      //Bitmap bitmap = new Bitmap(ms); 
      if (width == null) 
       extents.Cx = (long)bitmap.Width * (long)((float)914400/bitmap.HorizontalResolution); 
      else 
       extents.Cx = width * (long)((float)914400/bitmap.HorizontalResolution); 

      if (height == null) 
       extents.Cy = (long)bitmap.Height * (long)((float)914400/bitmap.VerticalResolution); 
      else 
       extents.Cy = height * (long)((float)914400/bitmap.VerticalResolution); 

      bitmap.Dispose(); 

      t2d.Extents = extents; 
      ShapeProperties sp = new ShapeProperties(); 
      sp.BlackWhiteMode = DocumentFormat.OpenXml.Drawing.BlackWhiteModeValues.Auto; 
      sp.Transform2D = t2d; 
      DocumentFormat.OpenXml.Drawing.PresetGeometry prstGeom = new DocumentFormat.OpenXml.Drawing.PresetGeometry(); 
      prstGeom.Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle; 
      prstGeom.AdjustValueList = new DocumentFormat.OpenXml.Drawing.AdjustValueList(); 
      sp.Append(prstGeom); 
      sp.Append(new DocumentFormat.OpenXml.Drawing.NoFill()); 

      DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture picture = new DocumentFormat.OpenXml.Drawing.Spreadsheet.Picture(); 
      picture.NonVisualPictureProperties = nvpp; 
      picture.BlipFill = blipFill; 
      picture.ShapeProperties = sp; 

      Position pos = new Position(); 
      pos.X = x * 914400/72; 
      pos.Y = y * 914400/72; 
      Extent ext = new Extent(); 
      ext.Cx = extents.Cx; 
      ext.Cy = extents.Cy; 
      AbsoluteAnchor anchor = new AbsoluteAnchor(); 
      anchor.Position = pos; 
      anchor.Extent = ext; 
      anchor.Append(picture); 
      anchor.Append(new ClientData()); 
      wsd.Append(anchor); 
      wsd.Save(dp); 
     } 
     catch (Exception ex) 
     { 
      throw ex; // or do something more interesting if you want 
     } 
    } 

私が最初の方法(ディスク上の実際のファイルを使用)を起動すると、それは問題ありません。私の写真をExcelファイルに挿入できます。しかし、私がmemorystreamにファイルを読み込んでmethod2を呼び出すと、エラーメッセージのあるピクチャ矩形が見えます。

私の質問はどのようにmemorystream経由でExcelに画像を挿入できますか?私はディスク上にあまりにも多くのファイルを作成しないためです。

+0

これを簡略化するためにEPPplusのようなライブラリを使用してください。 [この類似の質問をチェック](http://stackoverflow.com/questions/11588704/adding-images-into-excel-using-epplus)。必要なコードは2行です: 'var picture = ws.Drawings.AddPicture(index.ToString()、logo); picture.SetPosition(index * 5、0、2、0); ' –

+0

私はEPPlusを使用できないと思うのですが、私はEPPlusを使用できないと思います。多すぎるコード – user2155362

+0

Bitmap(ms)コンストラクタ呼び出しはストリームからデータを読み込みます。したがって、Stream.Positionはもはやポジション0にはありません。必然的に、FeedData(ms)コールはゴミを読みとることになります。回避策は 'ms.Position = 0;'を追加することですが、ビットマップを不正にする可能性があります.Bitmapクラスで使用されるコーデックでは、ピクセルデータを遅延読み込みすることがあります。ビットマップオブジェクトを作成しないことを検討してください。 –

答えて

0

OK、私は解決策を見つけたと思います。

は、私は、文字列へのMemoryStreamのパラメータを変更し、それは以下のようにMemoryStreamをに変換:

MemoryStream ms = new System.IO.MemoryStream(System.Convert.FromBase64String(str)) 

さて、それは動作します。

私はopen xml sdk 2.5の生産性ツールから学びます。

0

は、私はあなたが最初のストリームからのビットマップ画像データを作成する必要があると考えてい

ソリューションは、スタックオーバーフローの上に、ここで、そのためにすでにあります

:ビットマップイメージ にバイト配列Iは、溶液からコードをコピー&ペースト
int w= 100; 
int h = 200; 
int ch = 3; //number of channels (ie. assuming 24 bit RGB in this case) 

byte[] imageData = new byte[w*h*ch]; //you image data here 
Bitmap bitmap  = new Bitmap(w,h,PixelFormat.Format24bppRgb); 
BitmapData bmData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); 
IntPtr pNative  = bmData.Scan0; 
Marshal.Copy(imageData,0,pNative,w*h*ch); 
bitmap.UnlockBits(bmData); 
+1

これは、これが由来するSO答えへのリンクを追加することができます – Metoniem

関連する問題