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 = 3; // 에러카운트 - 운영자에게 에러 메세지가 너무 많이 날라가는것을 방지하기 위해


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

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

     cbThread.Abort();
     cbThread = null;
}

// 엑셀을 읽어 DB에 밀어 넣는다. - main
private void  ExcelDbInsert()
{
      // 인자값은 알아서 넣어 테스트
      Excel_Import(nExcelUID, nMastSheetID, strExcelReadFile, strImgDirName);
}


// 엑셀을 불러와 읽고 DB에 넣는다 - 실제처리
private void Excel_Import(int nExcelUID, int nMastSheetID, string strExcelReadFile, string strImgDirName)
{
    string strFilePathName = Path.GetFullPath(strExcelReadFile);
    string strErrMessage = "";

    // 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);

        // 유효성 검사를 위해
         Dictionary DicAnswer = new Dictionary();
        DicAnswer.Add("X", 0);
        DicAnswer.Add("x", 0);
        DicAnswer.Add("0", 1);
        DicAnswer.Add("O", 1);
        DicAnswer.Add("o", 1);
        DicAnswer.Add("N/A", 2);
        DicAnswer.Add("", 3);
        DicAnswer.Add("Blank", 3);

        // 선택한 시트를 연다 - oWBook.Worksheets[Index] 또는 oWBook.Worksheets["파일이름"]
        oWSheet = (Excel.Worksheet)oWBook.Worksheets[1];
        int nLastRow = oWSheet.Cells.get_End(Microsoft.Office.Interop.Excel.XlDirection.xlDown).Row;

        for (int nIdx = 2; nIdx <= nLastRow; nIdx++)
        {
            object objValue_1 = ((Excel.Range)oWSheet.Cells[nIdx, 1]).Value2;
            object objValue_2 = ((Excel.Range)oWSheet.Cells[nIdx, 2]).Value2;
            object objValue_3 = ((Excel.Range)oWSheet.Cells[nIdx, 3]).Value2;
            object objValue_4 = ((Excel.Range)oWSheet.Cells[nIdx, 4]).Value2;
            object objValue_5 = ((Excel.Range)oWSheet.Cells[nIdx, 5]).Value2;
            object objValue_6 = ((Excel.Range)oWSheet.Cells[nIdx, 6]).Value2;
            object objValue_7 = ((Excel.Range)oWSheet.Cells[nIdx, 7]).Value2;
            object objValue_8 = ((Excel.Range)oWSheet.Cells[nIdx, 8]).Value2;
            object objValue_9 = ((Excel.Range)oWSheet.Cells[nIdx, 9]).Value2;
            object objValue_10 = ((Excel.Range)oWSheet.Cells[nIdx, 10]).Value2;
            object objValue_11 = ((Excel.Range)oWSheet.Cells[nIdx, 11]).Value2;
            object objValue_12 = ((Excel.Range)oWSheet.Cells[nIdx, 12]).Value2;
            object objValue_13 = ((Excel.Range)oWSheet.Cells[nIdx, 13]).Value2;
            object objValue_14 = ((Excel.Range)oWSheet.Cells[nIdx, 14]).Value2;
            object objValue_15 = ((Excel.Range)oWSheet.Cells[nIdx, 15]).Value2;

            string strValue_1 = NullCheck_Object(objValue_1);
            string strValue_2 = NullCheck_Object(objValue_2);
            string strValue_3 = NullCheck_Object(objValue_3);
            string strValue_4 = NullCheck_Object(objValue_4);
            string strValue_5 = NullCheck_Object(objValue_5);
            string strValue_6 = NullCheck_Object(objValue_6);
            string strValue_7 = NullCheck_Object(objValue_7);
            string strValue_8 = NullCheck_Object(objValue_8);
            string strValue_9 = NullCheck_Object(objValue_9);
            string strValue_10 = NullCheck_Object(objValue_10);
            string strValue_11 = NullCheck_Object(objValue_11);
            string strValue_12 = NullCheck_Object(objValue_12);
            string strValue_13 = NullCheck_Object(objValue_13);
            string strValue_14 = NullCheck_Object(objValue_14);
            string strValue_15 = NullCheck_Object(objValue_15);

            int nMastSheetUID;
            int nCheckItemID;
            int nAnswer;
            int.TryParse(strValue_1, out nMastSheetUID);
            int.TryParse(strValue_2, out nCheckItemID);
            nAnswer = DicAnswer[strValue_12];
            Excel.Range oRangeImg = (Excel.Range)oWSheet.Cells[nIdx, 16];        // 셀의 위치 값을 가져오기 위해
              double dLeft = (double)oRangeImg.Left;                               // 원하는 영역의 그림을 가져오기 위해
              double dTop = (double)oRangeImg.Top;                                 // 원하는 영역의 그림을 가져오기 위해
              double dRight = (double)oRangeImg.Width + dLeft;                     // 원하는 영역의 그림을 가져오기 위해
              double dBotton = (double)oRangeImg.Height + dTop;                    // 원하는 영역의 그림을 가져오기 위해
              string strSaveFileImg = "";

            // 원하는 위치에서 엑셀 이미지를 클립보드에 넣는다.
            if (Picture_CopyToClipBoard(oWSheet, dLeft, dTop, dRight, dBotton))  
            {
                if (Clipboard.ContainsImage())
                {
                    strSaveFileImg = GetFileName_Image(strImgDirName, nCheckItemID.ToString());   // 이미지 파일 이름생성
                    System.Drawing.Image img = Clipboard.GetImage();                              // 클립보드에 있는것을 이미지로 저장
                    img.Save(strSaveFileImg);                                                     // 파일저장
                    Clipboard.Clear();
                }
            }

            Modify_MastCheckItem_Excel(nMastSheetUID, nCheckItemID, nAnswer, strValue_15, strSaveFileImg);
        }

        // 작업을 완료하고 DB에 저장
         Update_ExcelWork(nExcelUID, strExcelReadFile, 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 bool Picture_CopyToClipBoard(Excel.Worksheet oWSheet, double dLeft, double dTop, double dRight, double dBotton)
{
    // 좌표의 오차범위 설정
    double dErr = 0.5;
    double dTmpLeft;
    double dTmpTop;
    double dTmpRight;
    double dTmpBotton;
    dLeft -= dErr;
    dTop -= dErr;
    dRight += dErr;
    dBotton += dErr;

    for (int i = 0; i < oWSheet.Shapes.Count; i++)
    {
        Excel.Shape oShape = oWSheet.Shapes.Item(i);
        dTmpLeft = (double)oShape.Left;
        dTmpTop = (double)oShape.Top;
        dTmpRight = (double)oShape.Width + dTmpLeft;
        dTmpBotton = (double)oShape.Height + dTmpTop;

        if (dTmpLeft >= dLeft && dTmpTop >= dTop && dTmpRight <= dRight && dTmpBotton <= dBotton)
        {// 원하는 좌표에서 Control인 존재하고

              if (oShape.Type == MsoShapeType.msoPicture)
            {// 그림이라면
                Excel.Picture pict = oWSheet.Pictures(oShape.Name) as Excel.Picture;
                pict.CopyPicture(Microsoft.Office.Interop.Excel.XlPictureAppearance.xlScreen, Microsoft.Office.Interop.Excel.XlCopyPictureFormat.xlBitmap);
                return true;
            }
        }
    }
    return false;
}


// 값이 NULL 이면 공백으로 변환
private string NullCheck_Object(object objValue)
{
    if (objValue == null)
    {
        return "";
    }
    else
    {
        return objValue.ToString();
    }
}

// 저장할 그림파일이름이 동일하면 다른이름으로 변경
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;
}}

댓글 없음:

댓글 쓰기