2017-05-22 14 views
1

私はチャートを持つExcelファイルを持っています。これらのチャートは、私のプログラムではデータを表していますが、これらのデータを列やチャートの変更でも変更してから、私は、例外HRESULTが会った:0x80030020(STG_E_SHAREVIOLATION)excel chartを画像としてエクスポート

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.IO; 
using System.Linq; 
using Excel = Microsoft.Office.Interop.Excel; 
using RTO.Models; 
using Novacode; 
using System.Drawing; 
using Word = Microsoft.Office.Interop.Word; 
using System.Reflection; 
using CommonLib.SharedModels; 

namespace RTO 
{ 
    class Program 
    { 
     public static void ReportRTO(RtoCommonData cmnData, List<Antenna> antennas) 
     { 
      Novacode.Image imageh, imagev, image1, image2; 
      Picture pictureh, picturev, picture1, picture2; 
      Paragraph pimg; 

      var exApp = new Excel.Application(); 
      exApp.ScreenUpdating = false; 
      var exBook = exApp.Workbooks.Open(fileLeaf); 
      var exSheet = exBook.Worksheets[1] as Excel.Worksheet; 
      Excel.Range r1 = exSheet.get_Range("A1", "A360"); 
      Excel.Range r2 = exSheet.get_Range("B1", "B360"); 
      double[,] d1 = new double[360, 1]; 
      double[,] d2 = new double[360, 1]; 
      int w = 1; 

      var application = new Excel.Application(); 
      application.ScreenUpdating = false; 
      var workbook = application.Workbooks.Open(fileExcel); 
      var worksheet = workbook.Worksheets[1] as Excel.Worksheet; 
      Excel.Range rng1 = worksheet.get_Range("A1", "A361"); 
      Excel.Range rng2 = worksheet.get_Range("B1", "B361"); 
      Excel.Range rng3 = worksheet.get_Range("C1", "C361"); 
      Excel.Range rng4 = worksheet.get_Range("D1", "D361"); 
      double[,] data1 = new double[361, 1]; 
      double[,] data2 = new double[361, 1]; 
      double[,] data3 = new double[361, 1]; 
      double[,] data4 = new double[361, 1]; 
      int flnmadd = 1; 

      for (int i = 0; i < antennas.Count; i++) 
      { 
       //Save chart as image 
       w = 1; 
       foreach (Excel.Worksheet ws in exBook.Worksheets) 
       { 
        Excel.ChartObjects chartObjects = (Excel.ChartObjects)(ws.ChartObjects(Type.Missing)); 
        foreach (Excel.ChartObject co in chartObjects) 
        { 
         co.Select(); 
         Excel.Chart chart = co.Chart; 
         chart.Export(exportPath + @"\leaf" + w + ".png", "PNG", false); 
         w++; 
        } 
       } 

       //Insert image to doc 
       image1 = doc.AddImage(leafimg1); 
       picture1 = image1.CreatePicture(); 
       picture1.Width = 310; 
       picture1.Height = 310; 
       image2 = doc.AddImage(leafimg2); 
       picture2 = image2.CreatePicture(); 
       picture2.Width = 310; 
       picture2.Height = 310; 
       pimg = doc.InsertParagraph(); 
       pimg.AppendPicture(picture1); 
       pimg.AppendPicture(picture2); 

       for (int j = 0; j < boztrows; j++) 
       { 
        data1[j, 0] = sumbozres[i].Rxhor[j]; 
        data2[j, 0] = sumbozres[i].Rzhor[j]; 
        data3[j, 0] = sumbozres[i].Rxver[j]; 
        data4[j, 0] = sumbozres[i].Rzver[j]; 
       } 
       data1[boztrows, 0] = data1[0, 0]; 
       data2[boztrows, 0] = data2[0, 0]; 
       data3[boztrows, 0] = data3[0, 0]; 
       data4[boztrows, 0] = data4[0, 0]; 
       rng1.Value = data1; 
       rng2.Value = data2; 
       rng3.Value = data3; 
       rng4.Value = data4; 

       //Save chart as image 
       flnmadd = 1; 
       foreach (Excel.Worksheet ws in workbook.Worksheets) 
       { 
        Excel.ChartObjects chartObjects = (Excel.ChartObjects)(ws.ChartObjects(Type.Missing)); 
        foreach (Excel.ChartObject co in chartObjects) 
        { 
         co.Select(); 
         Excel.Chart chart = co.Chart; 
         chart.Export(exportPath + @"\charthv" + flnmadd + ".png", "PNG", false); 
         flnmadd++; 
        } 
       } 

       //Insert image to doc 
       if (antennas[i].Type == "БС") 
       { 
        imageh = doc.AddImage(charthimg); 
        pictureh = imageh.CreatePicture(); 
        pictureh.Width = 624; 
        pictureh.Height = 357; 
        imagev = doc.AddImage(chartvimg); 
        picturev = imagev.CreatePicture(); 
        picturev.Width = 624; 
        picturev.Height = 156; 
        pimg = doc.InsertParagraph(); 
        pimg.AppendPicture(pictureh); 
        pimg = doc.InsertParagraph(); 
        pimg.AppendPicture(picturev); 
       } 
       else if (antennas[i].Type == "РРС") 
       { 
        imageh = doc.AddImage(rrsimg); 
        pictureh = imageh.CreatePicture(); 
        pictureh.Width = 624; 
        pictureh.Height = 156; 
        pimg = doc.InsertParagraph(); 
        pimg.AppendPicture(pictureh); 
       } 

       trsprev += trs; 
       freqs = ""; 
       pows = ""; 
       koefgs = ""; 
       koefgrazs = ""; 
       poteri = ""; 
       poteriraz = ""; 
       freqAvg = 0; 
      } 

      exBook.Save(); 
      exBook.Close(); 
      exApp.Workbooks.Close(); 
      exApp.Quit(); 
      workbook.Save(); 
      workbook.Close(); 
      application.Workbooks.Close(); 
      application.Quit(); 
     } 
    } 
} 
+0

例外がここに表示されます:chart.Export(exportPath + @ "\ leaf" + w + ".png"、 "PNG"、false); –

+0

STG_E_SHAREVIOLATION: "別の呼び出し元がファイルを開いてロックしているためアクセスが拒否されました"。同じファイル名の古いファイルがオープン/使用中であるため、アクセスが拒否されていると推測されます。再実行する前に古いファイルを削除しましたか? – NLindbom

+0

@NLindbom問題は、同じ名前の同じ.pngファイルをループ内に作成して保存しているためです。まず、すべての反復後にファイルを削除しようとしましたが、「このファイルが開かれているため、削除できませんでした」というエラーがありました。だから、私は問題をすべてのグラフごとに異なる.pngファイルを作成して解決しました。しかし、それを行うには良い方法ですか、それとも良い方法がありますか? –

答えて

0

は、あなたのプログラムは、同じファイルの2つのインスタンスを持っていることだろう。画像を保存しようとする前にファイルを保存することもできます。

0

質問コメントで指摘されているとおり、HRESULT:0x80030020(STG_E_SHAREVIOLATION)は、「別の呼び出し元がファイルを開いてロックしているためアクセスが拒否されました」という詳細情報hereです。このファイルはまだオープン/使用中であり、最初に古いファイルを削除することで解決できます。

いくつかのオプションがあり、プログラムをどのように使用するかによって異なります。 try/catchステートメントを追加すると、プログラムがクラッシュすることはありません。それ以外にも、特にベストプラクティスはありません。使い方によって異なります。 私の意見では、保存に失敗した場合、プログラムが終了するのが控えめに合理的です。成功した場合には(きれいではありませんが、仕事をしていません)がtrueを返すのチャートを保存するための最初の方法:あなたがあなたの好みに合わせて調整することができソリューションを提供するの関心は

using System.IO; 

private static bool SaveExcelChartAsPNG(ChartObject co, 
    string path, string filename) 
{ 
    try 
    { 
     string filenamePNG = Path.ChangeExtension(filename, "png"); 
     string fullFilenamePNG = Path.Combine(path, filenamePNG); 

     co.Select(); 
     co.Chart.Export(fullFilenamePNG, "PNG", false); 
    } 
    catch 
    { 
     // Save was not successful 
     return false; 
    } 
    return true; 
} 

この解決策になります

  foreach (var co in chartObjects) 
      { 
       if (!SaveExcelChartAsPNG(exportPath, @"\leaf" + w + ".png")) 
        Application.Exit(); 
      } 

「w」パラメータを増分して10回保存する試行を繰り返す長い例では、ランダムなファイル名を試してください。それが機能しない場合、プログラムは終了します。

  //Save chart as image 
      w = 1; 
      foreach (var ws in exBook.Worksheets) 
      { 
       var chartObjects = (Excel.ChartObjects)(ws.ChartObjects(Type.Missing)); 
       foreach (var co in chartObjects) 
       { 
        int retry = 0; 
        bool successfulSave = false; 
        while (!successfulSave && retry < 10) // retry by incerementing w parameter 10 times) 
        { 
         successfulSave = SaveExcelChartAsPNG(exportPath, @"\leaf" + w + ".png")) 
         retry++; 
         w++; 
        } 

        if (!successfulSave) 
        { 
         // Try again with random filename, otherwise exit 
         string filename = Path.GetRandomFileName(); 
         if (!SaveExcelChartAsPNG(exportPath, filename)) 
         { 
          // Save still not successful, exit 
          Application.Exit(); 
         } 
        } 
       } 
      } 

そして、上記のコードについての発言:(それは欠陥が初のオフ、あなたはすでに10のチャート11倍を生成する場合は、常に最初のチャートに0-99その後、あなたは完全にランダムで10のチャートで終わるだろうが生成されますので、どのような場合でも、まずはランダムな名前を生成したい場合があります)。 ほとんどの場合、すべての例外をキャッチしてtrue/falseを返すのは良くありません。将来の問題は、ファイル名に関連しない例外がいくつか発生した場合に発生する可能性があります。ユーザとプログラマの両方は、何が起こったかを知らないままになります。使用可能なファイル名を要求する方が良いでしょう。多分、出力ファイル名をプログラムの入力パラメータにして柔軟性を持たせてください。

最後のオプションは、新しいランダム出力ディレクトリを作成して空であることを保証し、そこに優先ファイル名を出力することです。また、ファイルを作成していないPath.GetTempFileName()を超える利点を持つPath.GetRandomFileName()を使用してください。

関連する問題