본문 바로가기

개발/C#

c#에서 오피스(워드, 엑셀등) 접근 방법 - COM object관련

c#에서 MS오피스(워드, 엑셀 등)를 핸들링을 할려면 굉장한 노가다가 필요합니다.

(참조)

https://www.add-in-express.com/creating-addins-blog/2013/11/05/release-excel-com-objects/

http://www.simpleisbest.net/archive/2005/05/31/156.aspx


COM object에 대한 자원해제를 제대로 하지 않는다면 화면에 보이지는 않지만 그렇다고 죽어있지도 않는 오피스 프로세스가 어딘가에 존재하게 됩니다. 그래서 일일히 해당 개체들을 받아서 'Marshal.ReleaseComObject();' 해줘야 하는데요. 그러다 보면 해당 개체에 대한 선언, 할당, 해제부문이 많아 소스가 길어지게 되고 유지보수 하는데 많은 자원을 낭비하게 될것입니다.


아니면 관리하는 클래스를 만들어서 사용하거나 또는 정적 메소드(Static Method)로 만들어서 사용을 하더군요. 또 하나로는 XML을 핸들링 하는 방법인데 그건 논외로 치겠습니다. 예) https://github.com/WordDocX/DocX


그런데 저는 해당 개체에 대한 생명주기관리를 제대로 하는 클래스를 만들 자신이 없었습니다. 오피스 관리를 하나의 파일(.cs)에 모든것을 담기에는 소스량이 많고 그렇다고 추상화 등을 통한 본격적인 설계를 진행하기에는 부담(부담보다는 실력이 안되겠죠..)스러울것같았습니다. 그리고 이미 MS에서 만들어준 API를(Microsoft.Office.Interop.Word.dll) 다시한번 감싸준다는게 의미가 없다고 보여지기도 하고요. 또한 정적 메소드로 사용하기에는 뭔가 부자연스럽고요(직전 프로젝트에서는 정적 메소드로 사용하긴 했습니다만;;)


그래서 결론적으로 생각을 한게 자주사용되는 부분을 확장 메소드(Extension Method)로 만들어서 사용을 하자 입니다. "정적메소드랑 차이가 없지 않느냐" 라고 말씀을 하신다면.. 그에 대해서 같이 설명을 드리고자 합니다.


오피스 개체의 생명주기관리는 Presenter(Controller), Service같은 업무 프로세스등을 담당하는 곳에서 해주고 자주 사용되는 기능들은 확장 메소드로 만들어서 좀더 접근하는데 자연스럽게 하자는 것입니다.


워드로 예들 들어보겠습니다.

하나의 테이블에서 특정한 행을 삭제하고자 할때 아래와 같은 내용이 필요합니다.

위의 소스를 메소드 또는 정적 메소드로 만들어야 할 것입니다.


하~ 그러면 저 기능을 사용할려면 매개변수로 뭘 넣어주면 좋을까요? 그리고..

Table을 관리하는 클래스를 만들까요? 이미 MS에서 만들어준걸 또 감싸기에는 심한 낭비가 들것 같습니다. Table만을 사용하는 정적클래스를(헬퍼클래스) 만들까요? 다음 개발자는 꼭 해당 정적클래스를 알고있어야 하겠습니다. 인수인계를 철저히 해야겠습니다!

 

그렇다면 확장 메소드를 추천하는 이유는 무엇일까요?

위와 같이 만들어 주고 사용자는 'table.DeleteRow(1);'만 실행해주면 됩니다.

Table개체에서 바로 사용하므로 일절방해없이 의식의 흐름대로 진행할수 있을것 같습니다.


저는 Table에 대한 모든 메소드를 알고있지는 않습니다. 

그러므로 인텔리센스를 통해서 유사한 메소드를 찾게되는데요.

'table.D'까지만 키보드를 쳐도 위의 메소드가 나오면서 바로바로 작성을 해나갈수 있습니다.


결론적으로 COM개체를 사용할 때 위의 방법처럼 사용한다면 좀더 개발하는데 편하게 하실수 있을것 같습니다. 또한 확장메소드를 남발하는건 좋지 않기때문에 자주 사용되는 부분만을 추가하도록 추천드립니다.