2011년 9월 5일 월요일

Asp.net(C#) 에서 Excel 파일(그림포함) 쓰기 <- DB

// 참조 추가를 누르고 
// .NET 탭에서 Microsoft.Office.Interop.Excel               추가
// .NET 탭에서  System.Windows.Forms                        추가
// Com 탭에서 Microsoft.Office.버전 Object Library          추가

using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
using System.IO;
using Microsoft.Office.Core;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Threading;
using System.Collections.Generic;


// 위의 using 을 추가하고 클래스 안에 아래 코딩

bool bFinished;
int _ErrCount = 0;

// 그림파일을 캡쳐하기 위해서는 (즉 클립보드사용하기위해) 응용프로그램 스레드 필요
protected void btnCheckItemCreateExcel_Click(object sender, EventArgs e)
{
        bFinished = false;
        Thread cbThread = new Thread(new ThreadStart(ExcelSave));
        cbThread.ApartmentState = ApartmentState.STA;
        cbThread.Start();
        cbThread.Join();

 while (bFinished == false)
        {
            if (bFinished == true)
            {
                break;
            }
        }

        cbThread.Abort();
        cbThread = null;
}

// DB 데이터를 엑셀에 저장한다.   - main
private void ExcelSave()
{
      // 알아서 인자값 생성
      Excel_Export(nExcelUID, nMastSheetID, strBaseReadFile, strExcelSave);
}

private void Excel_Export(int nExcelUID, int nMastSheetID, string strExcelReadFile, string strExcelSave)
{
    string strErrMessage = "";
    DataTable dt = GetLIst_MasterSheet_Receiver_Excel(nMastSheetID);

    // Excel 실행 
    Excel.Application oExcel;                                       // Excel 프로세스
    Excel.Workbook oWBook = null;                                   // 엑셀문서
    Excel.Worksheet oWSheet = null;                                 // 시트
    oExcel = new Excel.Application();                               // Excel 프로세스 생성
    oExcel.Visible = false;                                         // 엑셀창이 나타나지 않고 작업을 진행하기 위해서...

    try
    {
        // 엑셀파일을 연다
        oWBook = oExcel.Workbooks.Open(strExcelReadFile, Missing.Value, Missing.Value, Missing.Value,
                       Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlNoChange,
                       Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
        oWSheet = (Excel.Worksheet)oWBook.Sheets[1];     // 시트 선택

 int nCount = dt.Rows.Count;
        int nIdx = 2;                                                   // 입력할 엑셀 행의 시작위치
        _nIdxImage = 0;                                                 // 몇번째 이미지인지 알기위해
        int aaa = 0;

        foreach (DataRow dr in dt.Rows)
        {
            //Excel.Range oRange = (Excel.Range)oWSheet.get_Range("G" + nIdx.ToString(), "G" + nIdx.ToString());       // 여러개의 셀을 설정할수 있다
            Excel.Range oRCell_1 = (Excel.Range)oWSheet.Cells[nIdx, 1];     // 해당행의 A번째 열의 셀
            Excel.Range oRCell_2 = (Excel.Range)oWSheet.Cells[nIdx, 2];     // 해당행의 B번째 열의 셀
            Excel.Range oRCell_3 = (Excel.Range)oWSheet.Cells[nIdx, 3];     // 해당행의 C번째 열의 셀
            Excel.Range oRCell_4 = (Excel.Range)oWSheet.Cells[nIdx, 4];     // 해당행의 D번째 열의 셀
            Excel.Range oRCell_5 = (Excel.Range)oWSheet.Cells[nIdx, 5];     // 해당행의 E번째 열의 셀
            Excel.Range oRCell_6 = (Excel.Range)oWSheet.Cells[nIdx, 6];     // 해당행의 F번째 열의 셀
            Excel.Range oRCell_7 = (Excel.Range)oWSheet.Cells[nIdx, 7];     // 해당행의 G번째 열의 셀
            Excel.Range oRCell_8 = (Excel.Range)oWSheet.Cells[nIdx, 8];     // 해당행의 H번째 열의 셀
            Excel.Range oRCell_9 = (Excel.Range)oWSheet.Cells[nIdx, 9];     // 해당행의 I번째 열의 셀
            Excel.Range oRCell_10 = (Excel.Range)oWSheet.Cells[nIdx, 10];   // 해당행의 J번째 열의 셀
            Excel.Range oRCell_11 = (Excel.Range)oWSheet.Cells[nIdx, 11];   // 해당행의 K번째 열의 셀
            Excel.Range oRCell_12 = (Excel.Range)oWSheet.Cells[nIdx, 12];   // 해당행의 L번째 열의 셀
            Excel.Range oRCell_13 = (Excel.Range)oWSheet.Cells[nIdx, 13];   // 해당행의 M번째 열의 셀
            Excel.Range oRCell_14 = (Excel.Range)oWSheet.Cells[nIdx, 14];   // 해당행의 N번째 열의 셀
            Excel.Range oRCell_15 = (Excel.Range)oWSheet.Cells[nIdx, 15];   // 해당행의 O번째 열의 셀
            Excel.Range oRCell_16 = (Excel.Range)oWSheet.Cells[nIdx, 16];   // 해당행의 P번째 열의 셀

     // 셀에 값 넣기
            oRCell_1.Value2 = dr["MastSheetID"].ToString();      // A
            oRCell_2.Value2 = dr["CheckItemID"].ToString();      // A
            oRCell_3.Value2 = dr["BcName"].ToString();           // B    
            oRCell_4.Value2 = dr["AssamblyFlow"].ToString();     // C
            oRCell_5.Value2 = dr["Category1"].ToString();        // D
            oRCell_6.Value2 = dr["Category2"].ToString();        // E
            oRCell_7.Value2 = dr["Category3"].ToString();        // F
            oRCell_8.Value2 = dr["ItemName"].ToString();         // G
            oRCell_9.Value2 = dr["Question"].ToString();         // H
            oRCell_10.Value2 = dr["Criterion"].ToString();       // I
            oRCell_11.Value2 = dr["HowToMessage"].ToString();    // J
            oRCell_12.Value2 = dr["Answer_Text"].ToString();     // K
            oRCell_13.Value2 = dr["Answer_Text"].ToString();     // L
            oRCell_14.Value2 = dr["ctq"].ToString();             // M
            oRCell_15.Value2 = dr["Comment"].ToString();         // N

     // 스타일 적용
            oRCell_1.Borders.LineStyle = 1;
            oRCell_2.Borders.LineStyle = 1;
            oRCell_3.Borders.LineStyle = 1;
            oRCell_4.Borders.LineStyle = 1;
            oRCell_5.Borders.LineStyle = 1;
            oRCell_6.Borders.LineStyle = 1;
            oRCell_7.Borders.LineStyle = 1;
            oRCell_8.Borders.LineStyle = 1;
            oRCell_9.Borders.LineStyle = 1;
            oRCell_10.Borders.LineStyle = 1;
            oRCell_11.Borders.LineStyle = 1;
            oRCell_12.Borders.LineStyle = 1;
            oRCell_13.Borders.LineStyle = 1;
            oRCell_14.Borders.LineStyle = 1;
            oRCell_15.Borders.LineStyle = 1;
            oRCell_16.Borders.LineStyle = 1;

            // 이미지 처리
            string strImgFileFullName = dr["tmImgFile"].ToString();
            if (string.IsNullOrEmpty(strImgFileFullName) == false)
            {
                Excel_WriteImage(oWSheet, oRCell_16, strImgFileFullName);
            }
            nIdx++;
        }

        // 파일 저장
        oWBook.SaveAs(strExcelSave, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
            Excel.XlSaveAsAccessMode.xlNoChange, Excel.XlSaveConflictResolution.xlLocalSessionChanges,
            Type.Missing, Type.Missing, Type.Missing, Type.Missing);

 // 작업을 완료하고 DB에 저장
        Update_ExcelWork(nExcelUID, strExcelSave, strErrMessage);
        _ErrCount = 0;
    }
    catch (Exception ex)
    {
        _ErrCount++;
        if (_ErrCount == 3)
        {
           // 에러를 관리자에게 알린다.
        }
    }
    finally
    {   // 프로세스를 종료해준다.
        // ※ 워크북 참조에 null 을 설정하지 않으면 프로세스가 종료되지 않음
        if (oWBook != null)
        {
            oWBook.Close(false, strExcelReadFile, Type.Missing);     // 닫기
            oWBook = null;
        }

        if (oExcel != null) // 작업후 프로세스가 남는 경우를 방지하기 위해서...
        {
            System.Diagnostics.Process[] pProcess;
            pProcess = System.Diagnostics.Process.GetProcessesByName("Excel");
            pProcess[0].Kill();
        }

        oExcel = null;
    }
}


// 파일이름 생성
private string GetFileName_Image(string strImgDirName, string strCheckItemID)
{
    string strFileName = strImgDirName + strCheckItemID + "_" + Path.GetRandomFileName() + ".jpg";
    return GetAvailablePathname(strFileName);
}


//---------------------------------------------------------------------------------------------------------------------------------
// 파일명이 중복일때 자동으로 이름을 생성 하는 코드
// 1. 파일명에 쓸수없는 특수문자 변경
// 2. 만약 test.txt라는 파일명이 중복일때 test(2).txt,test(3).txt ... 와 같이 중복일때 수치증가로 생성
//---------------------------------------------------------------------------------------------------------------------------------
private string GetAvailablePathname(string strFileFullName)
{
    string strFolderPath = Path.GetDirectoryName(strFileFullName) + "\\";
    string strFileName = Path.GetFileName(strFileFullName);
    int nInvalidChar = 0;

    do
    {
        nInvalidChar = strFileName.IndexOfAny(Path.GetInvalidFileNameChars());
        if (nInvalidChar != -1)
            strFileName = strFileName.Remove(nInvalidChar, 1);
    }
    while (nInvalidChar != -1);

    string fullPath = Path.Combine(strFolderPath, strFileName);
    string filenameWithoutExtention = Path.GetFileNameWithoutExtension(strFileName);
    string extension = Path.GetExtension(strFileName);

    while (File.Exists(fullPath))
    {
        Regex rg = new Regex(@".*\((?\d*)\)");
        Match mt = rg.Match(fullPath);

        if (mt.Success)
        {
            string numberOfCopy = mt.Groups["Num"].Value;
            int nextNumberOfCopy = int.Parse(numberOfCopy) + 1;
            int posStart = fullPath.LastIndexOf("(" + numberOfCopy + ")");
            fullPath = string.Format("{0}({1}){2}", fullPath.Substring(0, posStart), nextNumberOfCopy, extension);
        }
        else
        {
            fullPath = strFolderPath + filenameWithoutExtention + " (2)" + extension;
        }
    }
    return fullPath;
}

댓글 3개:

  1. Excel_WriteImage 함수는 별도로 구현하신 건가요? 소스엔 없는거 같은데 사용 할 수가 없네요ㅠ

    답글삭제