2014-02-13 2 views
3

Я triying для создания изображения с листа excel. После долгих исследований, я использую следующий код, но в какой-то момент я получаю исключение:Как я могу экспортировать таблицу Excel в качестве изображения?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Office.Interop.Excel; 

namespace ConsoleApplication1 
{ 
    class Prueba 
    { 
     [STAThread] 
     static void Main(string[] args) 
     { 
      var a = new Microsoft.Office.Interop.Excel.Application(); 

      try 
      { 
       Workbook w = a.Workbooks.Open(@"C:\SCRATCH\Libro2.xlsx"); 
       Worksheet ws = w.Sheets["Report"]; 
       ws.Protect(Contents: false); 
       Range r = ws.Range["B2:H20"]; 
       r.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap); 
       a.DisplayAlerts = false; 

       // System.Runtime.InteropServices.COMException Excepción de HRESULT: 0x80010105 (RPC_E_SERVERFAULT) 
       ChartObject chartObj = ws.ChartObjects().Add(r.Left, r.Top, r.Width, r.Height); 

       chartObj.Activate(); 
       Chart chart = chartObj.Chart; 
       chart.Paste(); 
       chart.Export(@"C:\SCRATCH\image.JPG", "JPG"); 
       chartObj.Delete(); 
       w.Close(SaveChanges: false); 
      } 
      finally 
      { 
       a.Quit();     
      } 

     } 
    } 
} 

Я использую офис 2013, 64 бит, Windows 7 64 и .Net 4.5.

+0

Какое исключение вы получаете и на какой строке? –

+0

Под строкой с комментарием, я получаю то, что комментарий говорит –

+0

Извините - пропущено это –

ответ

2

Это работает для меня в проекте WinForms:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using Excel = Microsoft.Office.Interop.Excel; 
using ios = System.Runtime.InteropServices; 

namespace ClipBoardTest 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     public void ExportRangeAsJpg() 
     { 
      Excel.Application xl; 

      xl = (Excel.Application)ios.Marshal.GetActiveObject("Excel.Application"); 

      if (xl == null) 
      { 
       MessageBox.Show("No Excel !!"); 
       return; 
      } 

      Excel.Workbook wb = xl.ActiveWorkbook; 
      Excel.Range r = wb.ActiveSheet.Range["A1:E10"]; 
      r.CopyPicture(Excel.XlPictureAppearance.xlScreen, 
          Excel.XlCopyPictureFormat.xlBitmap); 

      if (Clipboard.GetDataObject() != null) 
      { 
       IDataObject data = Clipboard.GetDataObject(); 

       if (data.GetDataPresent(DataFormats.Bitmap)) 
       { 
        Image image = (Image)data.GetData(DataFormats.Bitmap, true); 
        this.pict1.Image = image; 
        image.Save(@"C:\_Stuff\test\sample.jpg", 
         System.Drawing.Imaging.ImageFormat.Jpeg); 
       } 
       else 
       { 
        MessageBox.Show("No image in Clipboard !!"); 
       } 
      } 
      else 
      { 
       MessageBox.Show("Clipboard Empty !!"); 
      } 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      ExportRangeAsJpg(); 
     } 



    } 
} 

Для консольного приложения вы должны увидеть также: http://blog.another-d-mention.ro/programming/c/use-clipboard-copypaste-in-c-console-application/

+0

Ваш ответ в порядке. Но по какой-то причине я получаю исключение. Я открыл новый вопрос для решения этой проблемы: http://stackoverflow.com/questions/21850999/how-can-i-avoid-this-exception-when-copying-a-selected-range-in-excel –

+0

Примечание. что вам не нужно использовать буфер обмена - вы можете просто бросить книгу в IDataObject и получить формат растрового изображения для выбранного листа. Также Jpeg является ужасным выбором для крышки экрана Excel (этот формат оптимизирован для фотографии, для этой цели Jpeg будет представлять визуальные артефакты) - вместо этого кодируйте изображение как PNG. – BrainSlugs83

1

Может быть проще в VBA:

Sub PictureSaver() 
    Dim ch As Chart 
    Charts.Add 
    Set ch = ActiveChart 
    Sheets("Sheet4").Select 
    Range("A1:D4").Select 
    Selection.CopyPicture Appearance:=xlScreen, Format:=xlPicture 
    ch.Select 
    ch.Paste 
    ch.Export Filename:="sample.jpg" 
    Application.DisplayAlerts = False 
     ch.Delete 
    Application.DisplayAlerts = True 
End Sub 
+0

Могу ли я использовать автономный VBA? Я спрашиваю, потому что мне нужно делать больше вещей, таких как запрос к базе данных и другим операциям. –

+0

** Отличный вопрос! ** Возможно, можно изменить скрипт, чтобы запустить «снаружи» книгу .......... .Я открою новое сообщение, чтобы задать вопрос ..... –

+0

способ отпраздновать приятель !! – Tomamais

2

Не нужно создавать объект Chart. Вызов CopyPicture() на Range помещает изображение в системный буфер обмена. Вы можете закончить его в качестве лишь два шага, если вы хотите:

 Workbook w = a.Workbooks.Open(@"C:\SCRATCH\Libro2.xlsx"); 
     Worksheet ws = w.Sheets["Report"]; 
     ws.Protect(Contents: false); 
     Range r = ws.Range["B2:H20"]; 
     r.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap); 

     Bitmap image = new Bitmap(Clipboard.GetImage()); 
     image.Save(@"C:\SCRATCH\image.png"); 

     // charting code, replaced with the above 
       /* ChartObject chartObj = ws.ChartObjects().Add(r.Left, r.Top, r.Width, r.Height); 

       chartObj.Activate(); 
       Chart chart = chartObj.Chart; 
       chart.Paste(); 
       chart.Export(@"C:\SCRATCH\image.JPG", "JPG"); 
       chartObj.Delete(); */ 

EDIT: проверка Оставив все ошибки и управления потоком для вас, но было бы целесообразно, конечно, (по крайней мере) использовать ContainsImage() метод класса Clipboard, прежде чем пытаться получить доступ к его контенту.

+0

Те же комментарии, что и выше, - не нужно перезаписывать буфер обмена - просто запустите объект Workbook как объект IDataObject напрямую - это работает. – BrainSlugs83

Смежные вопросы