! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

C# 및 WPF를 사용하여 Excel 스프레드 시트를 가져오고 내보내는 방법 > 온라인 스터디

본문 바로가기

8. Excel 입출력 C# 및 WPF를 사용하여 Excel 스프레드 시트를 가져오고 내보내는 방법

페이지 정보

작성자 GrapeCity 작성일 2020-06-29 00:00 조회 1,580회 댓글 0건

본문

비즈니스 환경, 특히 금융 분야에서 일할 때 주식을 모니터링하는 것이 일반적입니다. 본인이나 고객/최종 사용자를 위해 큰 결정을 내릴 때는 시장의 과거, 현재 그리고 미래의 방향과 위치를 ​​알아야 합니다. 이러한 주식과 관련된 데이터를 가져와 효과적으로 이를 평가한 다음 명확한 결정을 내릴 수 있는 능력이 필요합니다. 말할 것도 없이 고객이나 최종 사용자를 위해 데이터를 내보내는 것이 일반적이므로 그들은 모든 데이터를 쉽게 시각화하고 이해할 수 있습니다.


이 글에서는 Spread.NET에서 C# 및 WPF(Windows Presentation Foundation)을 사용하여 애플리케이션을 빌드하는 방법을 보여줍니다이 애플리케이션은 Excel 스프레드 시트 가져오는 프로세스를 통해 다양한 주식 기호를 위한 3개월 분의 종가 기록을 가져오고 검색합니다. 또한 애플리케이션은 새 데이터를 포함한 Excel 스프레드 시트를 내보낼 수 있습니다.


이 애플리케이션의 목표는 외부 Excel 문서 가져오기를 통해 일련의 주식 기호를  사용자에게 제공할 수 있도록 하는 것입니다. 그런 다음 이러한 기호는 애플리케이션에서 처리됩니다.


  • REST API를 통해 각 주식의 3개월 종가 기록을 검색합니다.
  • API에서 검색된 기록 데이터는 스프레드 시트 구성 요소에서 기호와 함께 표시됩니다.
  • 인라인 스파크라인 차트(Inline Sparkline Chart)를 사용하여 주가 기록의 시각화를 추가합니다.
  • 처리 후 사용자는 결과 데이터를 새 Excel 문서로 내보낼 수 있습니다.


앱 빌드를 시작하겠습니다.


WPF 애플리케이션 구축


먼저 Spread.NET 평가판을 다운로드하고 설치해야 합니다설치 프로세스가 완료되면 Visual Studio 2019를 열고 새 WPF(.Net Framework) 데스크톱 애플리케이션 프로젝트를 만듭니다. 프로젝트 이름을 StockTrends.WPF로 지정했습니다.


WPF 응용 프로그램 구축


솔루션이 Visual Studio에서 로드가 완료되면 편집기에서 MainPage.xaml을 연 다음 Visual Studio Toolbox(CTRL + ALT + X)를 엽니다. ComponentOne Spread라는 도구 상자 섹션이 보이지 않으면 스프레드 시트 구성 요소를 도구 상자에 수동으로 추가해야 합니다. 운 좋게도이 작업은 한 번만 수행하면 됩니다. 도구 상자 패널에서 마우스 오른쪽 버튼을 클릭하여 구성 요소를 추가하고 메뉴에서 항목 선택(Choose Items)을 선택합니다.


WPF 응용 프로그램 구축


그런 다음 도구 상자 항목 선택 대화 상자에서 WPF 구성 요소(WPF Components) 탭이 선택되어 채워질 때까지 기다립니다(몇 분 소요 시간이 있음). 목록을 스크롤하여 GrapeCity.WPF.SpreadSheet.UI 네임 스페이스에 있는 GcSpreadSheet 있는 구성 요소 옆의 체크박스를 클릭하고 OK 버튼을 누릅니다.


WPF 응용 프로그램 구축


이제 XAML 문서에 도구 상자로부터 끌어다 놓을 수 있는 GcSpreadSheet 컨트롤을 사용할 수 있습니다.


WPF 응용 프로그램 구축


WPF 애플리케이션의 사용자 인터페이스 정의


우리는 WPF 애플리케이션의 요구사항을 만족시키기 위해 두 개의 행으로 구성된 간단한 창을 만들 것입니다. 첫 번째 행은 Spread.NET 스프레드 시트 구성 요소를 수용할 넓은 영역으로 구성됩니다. 아래에는 기호 스프레드 시트를 가져올 버튼 하나와 처리 후, 결과를 내보내는 버튼 하나로 총 2개의 버튼을 넣을 예정입니다.

Visual Studio 편집기에서 MainPage.xaml 열고, 기존 그리드 요소를 다음 마크업으로 바꿉니다. :

<Grid>  
        <Grid.RowDefinitions>  
            <RowDefinition />  
            <RowDefinition Height="100" />  
        </Grid.RowDefinitions>  
        <Grid.ColumnDefinitions>  
            <ColumnDefinition />  
            <ColumnDefinition />  
        </Grid.ColumnDefinitions>  
        <Button x:Name="btnLoadSpreadsheet" Grid.Row="1" Grid.Column="0"  
            Content="Load Spreadsheet" />  
        <Button x:Name="btnExportSpreadsheet" Grid.Row="1" Grid.Column="1"  
            Content="Export Spreadsheet" />  
   </Grid> 


창의 디자이너는 이제 다음과 유사하게 나타납니다.


WPF 응용 프로그램 구축


다음으로 GcSpreadSheet 구성 요소를 드래그하여 그리드의 첫 번째 셀에 놓습니다.


WPF 응용 프로그램 구축


스프레드 시트 구성 요소를 나타내는 XAML 요소를 편집하여 다음과 일치하도록 합니다.

<ss:GcSpreadSheet x:Name="spreadControl" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"/>  


디자이너는 이제 다음과 유사하게 나타납니다.

Spread.NET 구성 요소로 Excel 파일 가져 오기


스프레드 시트 구성 요소로 Excel 파일 가져오기


구현할 기능의 첫 번째는 외부 Excel 파일을 Spread.NET 스프레드 시트 구성 요소로 가져 오는 것입니다. Excel 스프레드 시트에는 사용자가 애플리케이션에서 처리하려는 주식 기호 목록이 포함되어 있습니다.


이 기능을 Microsoft.Win32 네임 스페이스의 OpenFileDialog 클래스를 사용하여 구현합니다. 클래스를 사용하면 대화 상자에 필터를 추가하여 사용자가 기존 Excel(*. xlsx) 문서에서 빠르게 선택할 수 있도록 합니다. 파일이 선택되면 스프레드 시트는 한 줄의 코드를 사용하여 스프레드 시트 구성 요소에 로드됩니다!


MainPage.xaml 디자이너에서 스프레드 시트 로드(Load SpreadSheet) 버튼 더블 클릭해 클릭 핸들러를 구현합니다. 다음과 같이 코드를 구현합니다.

private void BtnLoadSpreadsheet_Click(object sender, RoutedEventArgs e)  
       {  
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();  
            ofd.DefaultExt = ".xlsx";  
            ofd.Filter = "Excel Documents (*.xlsx)|*.xlsx";  
            var sel = ofd.ShowDialog();  
            if (sel==true)    
            {  
                //one line of code to import the Excel file into Spread.NET  
                spreadControl.OpenExcel(ofd.FileName);  
            }  
        }  


다음으로 주식 기호 목록이 포함된 Excel에 간단한 스프레드 시트를 만듭니다. 이 문서는 하나의 열이 있는 단일 워크 시트로 구성됩니다. 이 열에 처리할 주식 기호를 입력합니다. (이 예제에서는 애플리케이션 코드 자체에 집중할 수 있도록 데이터 정리 또는 오류 처리를 수행하지 않으므로 스프레드 시트의 형식을 지정하는 방법에 대한 몇 가지 규칙이 있습니다. 행당 하나의 티커 기호만 있습니다. 유효한 티커 기호만 입력했는지 확인해주시기 바랍니다.) 



애플리케이션을 실행하고 방금 만든 Excel 파일을 선택합니다. 그런 다음 파일을 불러와서 애플리케이션의 스프레드 시트 컨트롤에 표시됩니다.



Spread.NET에서 Excel 파일 내보내기


이제 가져오기 프로세스 기능이 있으므로 내보내기 기능 구현으로 넘어갑니다. 대화 상자에서 확장 필터를 설정할 수 있으므로 Microsoft.Win32 네임 스페이스에 있는 SaveFileDialog 클래스를 사용합니다Spread.NET 구성 요소에서 Excel 문서를 내보내는 기능도 한 줄의 코드로 간단하게 처리 할 수 ​​있습니다.


MainPage.xaml의 디자이너에서 클릭 이벤트 핸드러 코드를 구현하기 위해 스프레드 시트 내보내기(Export SpreadSheet) 버튼을 더블 클릭합니다. 다음과 같이 핸들러 코드를 구현합니다.

      private void BtnExportSpreadsheet_Click(object sender, RoutedEventArgs e)  
        {  
            Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog();  
            sfd.FileName = "SpreadNET.xlsx";  
            sfd.Filter = "Excel Documents (*.xlsx)|*.xlsx";  
            sfd.DefaultExt = ".xlsx";  
            var sel = sfd.ShowDialog();  
            if (sel == true)  
            {  
                spreadControl.SaveExcel(sfd.FileName,  
                    GrapeCity.Windows.SpreadSheet.Data.ExcelFileFormat.XLSX);  
            }  
        }  


애플리케이션을 한 번 더 실행하고 주가 스프레드 시트를 다시 한 번 로드한 다음, 스프레드 시트 내보내기 버튼을 눌러 표시된 스프레드 시트의 복사본을 컴퓨터에 저장합니다.


과거 주식 데이터 검색


애플리케이션을 위해, IEX Cloud에서 무료 계정을 만들어 스프레드 시트에서 3개월 간의 종가 기록을 검색하었습니다. 계정을 등록했다면, IEX Cloud API와 함께 사용할 API 토큰을 얻을 수 있는 대시 보드 콘솔에 들어갈 수 있습니다.



API를 호출시, 주식 기호의 전체 목록을 이미 알고 있습니다. 단일 호출을 통해 모든 데이터를 얻을 수 있도록 일괄 처리 엔드 포인트를 사용합니다.


API와의 통합을 구현하기 위해 두 가지 NuGet 패키지를 사용합니다. 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 NuGet 패키지 관리 옵션을 선택합니다. 찾기(Browse) 탭을 누른 다음, Newtonsoft.JSON과 RestSharp 패키지를 검색 및 설치합니다.



그런 다음 프로젝트를 마우스 오른쪽 단추으로 클릭하고 StockHistoryRetriever라는 새 클래스를 추가합니다이 파일은 API 통합과 관련된 모든 코드를 캡슐화합니다. 또한 IEX Cloud API의 데이터 구조를 반영하는 두 개의 추가 클래스에 대한 정의도 포함합니다.


이 파일에는 데이터 캡슐화 클래스 외에도 재무 API를 호출을 담당하는 메소드가 포함되어 있습니다. StockHistoryRetriever의 코드 목록은 다음과 같습니다.(API_TOKEN 값을 IEX Cloud 대시 보드에서 사용자 고유 값으로 대체)

using Newtonsoft.Json.Linq;  
using RestSharp;  
using System;  
using System.Collections.Generic;

namespace StockTrends.WPF  
{  
    public class StockHistoryRetriever  
    {  
        private const string API_TOKEN = "<YOUR PUBLISHABLE API TOKEN>";  
        private const string BASE_URL = "https://cloud.iexapis.com";  
        private const string API_VERSION = "beta";

        public List<ClosingStockHistory> Get3MonthHistory(List<string> symbols)  
        {  
            var client = new RestClient(BASE_URL);  
            var endpoint = $"{API_VERSION}/stock/market/batch";  
            var request = new RestRequest(endpoint, Method.GET);  
            request.AddQueryParameter("symbols", string.Join(",", symbols));  
            request.AddQueryParameter("types", "chart");  
            request.AddQueryParameter("range", "3m");  
            request.AddQueryParameter("chartCloseOnly", "true");  
            request.AddQueryParameter("token", API_TOKEN);

            IRestResponse resp = client.Execute(request);  
            var stockHistory = JObject.Parse(resp.Content);

            var history = new List<ClosingStockHistory>();  
            foreach (var symbol in symbols)  
            {  
                var closingStockHistory = new ClosingStockHistory();  
                closingStockHistory.Symbol = symbol;  
                closingStockHistory.Prices = new List<ClosingPrice>();  
                var stock = stockHistory[symbol];  
                var chartData = (JArray)stock["chart"];  
                foreach (var itm in chartData)  
                {  
                    closingStockHistory.Prices.Add(new ClosingPrice() {  
                        Date = Convert.ToDateTime(itm["date"]),  
                        Price = Convert.ToDouble(itm["close"]) });  
                }  
                history.Add(closingStockHistory);  
            }

            return history;  
        }  
    }

    public class ClosingStockHistory  
    {  
        public string Symbol { get; set; }  
        public List<ClosingPrice> Prices { get; set; }  
    }

    public class ClosingPrice  
    {  
        public DateTime Date { get; set; }  
        public double Price { get; set; }  
    }  
}



스프레드 시트에 주식 데이터 추가


Spread.NET 구성 요소에 심볼 스프레드 시트를 성공적으로 로드하면 API 호출을 발행하고 검색된 최종 가격 기록을 동일한 워크 시트에 다시 작성하는 데 필요한 모든 정보를 갖게 됩니다.


이 구현을 시작하려면 MainPage.xaml.cs를 열고 다음을 추가합니다.


using GrapeCity.Windows.SpreadSheet.Data;


MainPage 클래스에 다음 메소드를 추가합니다ProcessSpreadsheet 메소드는 API 호출을 발행하고 현재 워크 시트의 해당 행으로 가격 이력 데이터 작성, 업로드된 문서에서 기호의 목록을 읽기 등을 역할을 합니다.

private void ProcessSpreadsheet()  
{  
    List<string> stocks = new List<string>();  
    var worksheet = spreadControl.Sheets[0];  
    for (var i = 0; i < worksheet.RowCount; i++)  
    {  
        var stockSymbol = worksheet.Cells[i, 0].Text;  
        stocks.Add(stockSymbol);  
    }  
    StockHistoryRetriever retriever = new StockHistoryRetriever();  
    var data = retriever.Get3MonthHistory(stocks);  
    //calculate max columns required,  
    //increase the number of columns available in the worksheet  
    int maxCount = data.Max(x => x.Prices.Count());  
    worksheet.ColumnCount = maxCount + 1; //1 column for the symbol  
    //Similar to a CSS class, define header column style  
    var headerStyleName = "HeaderStyle";  
    var headerStyle = new StyleInfo()  
    {  
        Background = new SolidColorBrush(Colors.LightSeaGreen),  
        Name = headerStyleName,  
        BorderBottom = new BorderLine(Colors.SeaGreen),  
        BorderRight = new BorderLine(Colors.SeaGreen)  
    };  
    worksheet.NamedStyles.Add(headerStyle);  
    //set column header for the symbol assign header style  
    worksheet.ColumnHeader.Cells[0, 0].Text = "Symbol";  
    worksheet.ColumnHeader.Cells[0, 0].StyleName = headerStyleName;  
    bool setHeader = true;  
    foreach (var stock in data)  
    {  
        //find stock index  
        int rowIdx = 0;  
        int colIdx = 0;  
        spreadControl.Search(0, stock.Symbol, out rowIdx, out colIdx);  
        int columnCounter = 1;  
        foreach (var price in stock.Prices)  
        {  
            if (setHeader)  
            {  
                //set header text to date of the price,  
                //expand column width, set column header style  
                worksheet.ColumnHeader.Cells[0, columnCounter].Text =  
                    price.Date.ToString("MM/dd/yyyy");  
                worksheet.ColumnHeader.Cells[0, columnCounter].StyleName =  
                    headerStyleName;  
                worksheet.Columns[columnCounter].Width = 85;  
            }  
            //set cell to format to currency  
            worksheet.Cells[rowIdx, columnCounter].Formatter =  
                new GeneralFormatter(FormatMode.StandardNumericMode, "c");  
            worksheet.Cells[rowIdx, columnCounter].Value = price.Price;  
            columnCounter++;  
        }  
        setHeader = false;

        spreadControl.Invalidate();  
    }  
}



염두에 두어야 할 주요 사항 중 하나는 스프레드 시트의 크기를 변경한다는 것입니다. 처음 업로드 될 때 기호 시트는 행당 주식 기호가 정의된 단일 열로 구성되어 있습니다. 이전에 존재하지 않은 열에 작성을 시도하면 오류가 발생합니다. ColumnCount 속성에 원하는 총 열 수로 설정하여 워크 시트의 열 수를 조정합니다.


BtnLoadSpreadsheet_Click메소드에서 OpenExcel 문 바로 다음에 새 ProcessSpreadsheet 함수에 대한 ProcessSpreadsheet(); 호출을 추가합니다.


애플리케이션을 다시 실행하면 해당 주식 기호와 같은 행에 3개월 종가가 표시됩니다. 데이터를 오프라인으로 전환하려면 스프레드 시트를 내보내기 해야 합니다.



데이터 소스에서 스파크 라인 차트 생성


수집된 모든 데이터를 살펴 보는 것이 좋지만 시각 자료가 있다면 더 좋을 것 입니다. 스파크 라인 그래프를 사용하면 데이터를 한 눈에 파악할 수 있습니다. Spread.NET을 사용하면 강력한 API를 통해 스파크 라인 그래프를 만들 수 있습니다. 이 스파크 라인은 완전히 사용자 지정을 할 수 있으며 스프레드 시트에 이미있는 데이터를 사용하여 만들 수 있습니다.


다음 코드를 사용하여 ProcessSpreadsheet를 변경합니다.

private void ProcessSpreadsheet()  
{  
    List<string> stocks = new List<string>();  
    var worksheet = spreadControl.Sheets[0];  
    for (var i = 0; i < worksheet.RowCount; i++)  
    {  
        var stockSymbol = worksheet.Cells[i, 0].Text;  
        stocks.Add(stockSymbol);  
    }  
    StockHistoryRetriever retriever = new StockHistoryRetriever();  
    var data = retriever.Get3MonthHistory(stocks);  
    //calculate max columns required,  
    //increase the number of columns available in the worksheet  
    int maxCount = data.Max(x => x.Prices.Count());  
    //1 column for the symbol, 1 column for the sparkline  
    worksheet.ColumnCount = maxCount + 2;  
    //set sparkline column width  
    worksheet.Columns[1].Width = 500;

    //define header column style  
    var headerStyleName = "HeaderStyle";  
    var headerStyle = new StyleInfo() {  
        Background = new SolidColorBrush(Colors.LightSeaGreen),  
        Name = headerStyleName,  
        BorderBottom = new BorderLine(Colors.SeaGreen),  
        BorderRight = new BorderLine(Colors.SeaGreen)};  
    worksheet.NamedStyles.Add(headerStyle);  
    //set column header for the symbol and sparkline column - assign header style  
    worksheet.ColumnHeader.Cells[0, 0].Text = "Symbol";  
    worksheet.ColumnHeader.Cells[0, 0].StyleName = headerStyleName;  
    worksheet.ColumnHeader.Cells[0, 1].Text = "Trend";  
    worksheet.ColumnHeader.Cells[0, 1].StyleName = headerStyleName;  
    bool setHeader = true;  
    foreach (var stock in data)  
    {  
        //find stock index  
        int rowIdx = 0;  
        int colIdx = 0;  
        spreadControl.Search(0, stock.Symbol, out rowIdx, out colIdx);  
        int columnCounter = 2;  
        foreach (var price in stock.Prices)  
        {  
            //set header to date, expand column width, set column header style  
            if (setHeader)  
            {  
                worksheet.ColumnHeader.Cells[0, columnCounter].Text =  
                    price.Date.ToString("MM/dd/yyyy");  
                worksheet.ColumnHeader.Cells[0, columnCounter].StyleName =  
                    headerStyleName;  
                worksheet.Columns[columnCounter].Width = 85;  
            }  

            //set cell to format to currency  
            worksheet.Cells[rowIdx, columnCounter].Formatter =  
                new GeneralFormatter(FormatMode.StandardNumericMode, "c");  
            worksheet.Cells[rowIdx, columnCounter].Value = price.Price;  
            columnCounter++;  
        }  
        setHeader = false;  

        //create sparkline  
        var range = new CellRange(rowIdx, 2, 1, stock.Prices.Count);  
        var settings = new SparklineSetting();  
        settings.AxisColor = SystemColors.ActiveBorderColor;  
        settings.LineWeight = 1;  
        settings.ShowMarkers = true;  
        settings.MarkersColor = Color.FromRgb(255, 0, 128);  
        settings.ShowFirst = true;  
        settings.ShowHigh = true;  
        settings.ShowLast = true;  
        settings.ShowNegative = true;  
        settings.FirstMarkerColor = Color.FromRgb(163, 73, 164);  
        settings.HighMarkerColor = Color.FromRgb(49, 78, 111);  
        settings.LastMarkerColor = Color.FromRgb(0, 255, 255);  
        settings.NegativeColor = Color.FromRgb(255, 255, 0);  
        //set row height  
        worksheet.Rows[rowIdx].Height = 250;  
        worksheet.SetSparkline(rowIdx, 1, range, DataOrientation.Horizontal,  
            SparklineType.Line, settings);  
        spreadControl.Invalidate();         
    }  
}



ProcessSpreadsheet 코드는 이제 스파크 라인 열의 행 높이 및 열 너비를 설정합니다. 이 값을 설정하면 스파크 라인 그래프에 더 많은 공간이 생기면서 그래프를 보다 더 쉽게 ​​읽고 해석할 수 있게 되었습니다. 또한 색상과 같은 Sparkline 사용자 지정 설정을 확인하고 각 행에서 그래프를 생성하는 데 사용되는 셀 범위를 지정할 수 있습니다.



엑셀 스프레드 시트 구성 요소


이 글에서는 Spread.NET 스프레드 시트 구성 요소의 전체 기능의 일부만 설명합니다. 사용 가능한 여러 기능을 보기 위해 공식 문서를 참고해주시기 바랍니다. 스프레드 시트 구성 요소를 애플리케이션에 통합하면 사용자의 환경을 사용자가 정의하고  외부 프로그램을 참조하지 않고도 사용자에게 익숙한 스프레드 시트 기능을 제공할 수 있습니다.

  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그1

인기글

더보기
  • 인기 게시물이 없습니다.
메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.