어떻게 Excel의 단원격 등 대상을 그림으로 저장합니까

어떻게 Excel의 단원격 등 대상을 그림으로 저장합니까
2011-01-24 11:14:10
태그:Office
Excel의 많은 대상, 예를 들어 칸(Cell), 도형(shape), 도표(chart) 등은 때때로 그것들을 그림으로 저장해야 한다.캡처하는 것처럼.
최근에 Excel 관련 프로젝트를 하나 만들었는데 프로젝트에서 매우 변태적인 수요를 만나면 Excel 중의 일부 대상에 대해 그림을 찍어야 한다. 예를 들어 한 칸에 색깔을 설정한 후에 그림을 찍거나 도표, 보고서를 그림으로 찍어야 한다.비교적 우여곡절의 경험을 거쳐 마침내 완성하였다.꺼내서 나눠봐.
Excel을 하려면 먼저 Excel의com 대상 모델을 보아야 한다.주소는 다음과 같습니다.
http://msdn.microsoft.com/en-us/library/bb149081(v=office.12).aspx
여기에 설명합니다.
공식 Excel 2010 대상자는 참고로 찾지 못했습니다. 누르면 사순환입니다. 누르고 누르면 찾지 못합니다. 어떤 신인이 찾았는지 답장해 주세요. 
Excel 2003의 대상 모형은 아래로 내려가서 설치해야 하기 때문에 번거롭습니다. 저도 설치한 후에 알았습니다. 여기는 위의 사이트를 통해 Excel 2007의 모형을 보시면 된다고 추천합니다.실제로 마이크로소프트의 호환 관례에 따르면 Excel 2010과 Excel 2003의 차이는 크지 않을 것이다.
그 다음에는 Range 객체의 멤버를 살펴보고 Range 객체에 대해 알아볼 수 있는 방법이 없을지 기대해 봅니다.http://msdn.microsoft.com/en-us/library/bb225606(v=office.12).aspx
한 바퀴 돌았지만 ExportImage, SaveImage 같은 방법은 발견되지 않았다.낙담을 표시하는 것도 도리에 맞다.
절망 속에서 하나의 하이라이트를 발견했는데, 하나의 방법은 Copy Picture라고 한다.방법을 살펴보니 대상을 그림으로 복사해서 클립보드에 복사해야 한다는 것이다.허허, 비교적 비뚤어진 생각이 탄생했다. 이왕 클립보드에 복사할 수 있다면 나는 다시 클립보드에서 그림을 파내면 되잖아. 
좋아, 그렇게 하기로 했어, 하자면 해.
……
여기서 200자를 생략합니다. (excel의com 대상을 어떻게 만드는지, 랑의 대상을 어떻게 찾았는지 말하지 않겠습니다. 모르는 것은 스스로 찾아보셔도 됩니다. 질문에 답장할 수 있습니다.)
……
레인지 상대를 잡으면CopyPicture 메서드를 실행하려면 두 개의 매개 변수가 필요합니다.첫 번째 파라미터는 XlPicture Appearance 매거진이다. 1은 화면의 모양에 따라 복사하고, 2는 인쇄할 때의 모양에 따라 복사한다.두 번째 파라미터는 XlCopyPictureFormat 매거진으로 2는 비트맵으로 복사하고 -4147은 벡터 그림으로 복사한다.
그래서 나는 대략 다음과 같은 코드를 썼다.
 

   
   
   
   
  1. Range cell = excel.Activesheet.Cells[1,1];  
  2. cell.CopyPicture(1,2);  
  3. Bitmap image = Clipboard.GetImage() as Bitmap;  
  4. if(image != null) { // 。 } 

디버깅, 실행, 모든 Ok, 전혀 문제 없습니다. 코드를 제출합니다. (그 동안 무수한 추가 코드를 만들었습니다. 여기서는 언급하지 않습니다.)(헤헤, 이런 사소한 일로 건물주를 만날 수 있을까, 득의양양하게 웃는다.)
그리고 24시간이 지나고 다음 날이 왔대요.
출근하자마자 건물주가 흥겹게 메일을 보내서 여러분께 축하드립니다. excel의 사진 찍기 기능이 완성되었으니 얼른 드세요(enjoy).
모두들 잘 맞아서 "건물주 Nb야"같은 축전을 잇달아 보내왔다.
건물주의 허영심이 매우 큰 만족을 얻어 매우 기쁘다고 표시하였다.자아도취에 빠지다.
얼마 지나지 않아 같은 그룹의 1MM은 건물주의 이름을 놀라게 했다. "건물주, 건물주, 빨리 와서 보세요. 당신의 사진 찍는 기능이 정말 너무...."마지막으로 두 글자를 말하지 못했을 때, 건물주는 이미 MM의 곁으로 날아갔다.그나저나 MM은 참...(응, 일단 말하지 말자), "너무 기똥차니?"집주인은 자신 있게 남은 몇 글자를 보충했다.MM 손가락 스크린, "너의 사진이 왜 깨졌어."과연 스크린 위의 Null Reference Exception이 화면 중앙에 날뛰며 누워 있었다.건물주가 코드를 과감하게 디버깅하고 추적한 결과 사진 찍는 데 문제가 생겼습니다. 위의 클리프보드.GetImage()가 null로 반환되었습니다.그럴 리가요. 건물주가 또 몇 번을 반복해서 운행했는데 결과는 똑같아요. 모두null로 돌아왔어요.건물주는 배가 매우 크다고 표시했다.
그러나 오리는 오리에게 돌아간다. 건물주는 쉽게 지지 않는 사람이다. 입버릇은'나는 이 사악함을 믿지 않는다'는 것이다.이번에도 건물주가 말버릇을 하면서 계속 미행을 했다.
우선 클립보드의 데이터를 봐야죠. 복사가 성공했는지,
Clipboard.GetDataObject().GetFormats() 메서드가 반환됩니다.
  [0]: "EnhancedMetafile"
    [1]: "MetaFilePict"
    [2]: "Link"
보아하니 고문한 것 같다.그리고 건물주가 이 몇 개의format을 통해 get 데이터를 찾았지만 성공하지 못했다.그게 이상해.
건물주가 충격을 받아서 자리로 돌아와 계속 테스트를 했다.
같은 코드는 건물주 기계에선 멀쩡한데 왜 MM 기계에선 null일까.
건물주가 자신의 기계에서 클립보드 데이터를 다시 한 번 보았다.
Clipboard로.GetDataObject().GetFormats() 메서드가 반환됩니다.
[0]: "System.Drawing.Bitmap"
    [1]: "Bitmap"
    [2]: "DeviceIndependentBitmap"
    [3]: "Format17"
    [4]: "Link"
어, 왜 위와 다르지?건물주는 과감하게 건물주의 기계에 설치된 것은 Excel2010이고 mm의 기계에 설치된 것은 Excel2007.알고 보니 그들이 시험해 낸 데이터가 다르다.
과감하게 Google은그래서 몇 차례의 실패와 점프를 거쳐 건물주가 이곳에 왔다.http://support.microsoft.com/kb/323530/en-us/
비로소 문득 크게 깨달았다.Net의 일부 제한 사항은, 일부 오래된 프로그램 (예를 들어 여기에서 만난 Excel 2007) 을 클립보드에 복사한 데이터를 사용할 수 없기 때문에 로컬 Api를 통해 사용해야 한다.내가 갈게...msdn에도 반 글자의 알림이 없다.
건물주는 비교적 부지런한 사람이니 이것을 알았으면 빨리 손을 대지 마라.
그래서 건물 주인은 다음과 같은 코드를 썼다.
 

   
   
   
   
  1. IntPtr hwnd = excel.Hwnd; 
  2. try 
  3.             { 
  4.                 if (OpenClipboard(hwnd)) 
  5.                 { 
  6.                     IntPtr data = GetClipboardData(14); // CF_ENHMETAFILE      14 
  7.                     if (data != IntPtr.Zero) 
  8.                     { 
  9.                         using (Metafile mf = new Metafile(data, true)) 
  10.                         { 
  11. // , bitmap 。 。 
  12.                             Bitmap b = new Bitmap(mf); 
  13.                             return b; 
  14.                         } 
  15.                     } 
  16.                 } 
  17.             } 
  18.             finally 
  19.             { 
  20.                 CloseClipboard(); 
  21.             } 
  22.  
  23.  
  24.  
  25. [DllImport("User32.dll")] 
  26.         [return: MarshalAs(UnmanagedType.Bool)] 
  27.         public static extern bool OpenClipboard(IntPtr hWndNewOwner); 
  28.  
  29. [DllImport("User32.dll")] 
  30.         [return: MarshalAs(UnmanagedType.Bool)] 
  31.         public static extern bool CloseClipboard(); 
  32.  
  33. [DllImport("User32.dll")] 
  34.         public static extern IntPtr GetClipboardData(System.UInt32 uFormat); 

디버깅, 실행, 성공.허허, 또 득의양양하게 웃는다.코드를 제출합니다.
건물주가 또다시 흥미진진하게 여러분에게 메일을 보냈습니다. excel의 사진 촬영은 사용할 수 있습니다. 어서 와서 드세요.
그리고 다들 잘 맞아서 축전을 보냈어요. 그리고...
그리고...
그리고 뭐, 그리고 없어졌어요. 실망시켜서 미안해요. 이번에는 문제 없어요.됐어.득의양양하게 웃다.
요약:
1. 첫 번째 주의해야 할 것은 Excel 2007과 Excel 2010의 복사 데이터 형식이 다르기 때문에 특히 주의해야 한다.
2. excel에 있는 모든 CopyPicture 방법이 있는 대상은 이렇게 그림을 찍을 수 있음을 분명히 한다.대충 봤는데 많은 대상들이 이 방법을 가지고 있어요. 랑, 샤프, 차트 등등.
3. 또한Chart 대상에 대해 Export 방법이 하나 더 있어 그림으로 직접 내보낼 수 있다.
4. 부지런한 건물주가 위의 방법을 살짝 포장한 Win32 Clipboard Helper는 그 중의 Get Image를 사용하여 excel의 hwnd에 전송하면 클립보드에서 그림을 꺼낼 수 있다.부록에 올려 모두가 맛있게 먹을 수 있도록 하다.
5. 마지막으로 우정 알림, 어떤 원인으로 인해 윗글에 나타난 코드는 모두 설명 코드이고 실제 프로젝트와 무관하며 윗글의 코드가 번역되고 통과될 수 있다는 보장도 없다. 모두가 정신을 깨닫고 진실에 비교할 수 없다.
 
원본 다운로드
Win32ClipboardHelper.zip

좋은 웹페이지 즐겨찾기