2023年6月5日 星期一

c#幾個常用的匯入方式和元件

    各位有發現EXCEL的格式有分為.CSV.XLS .XLXS 等,但作法不儘相同,所以幫各位整理起來,希望各位網友可以善加利用。

一、CLOSEXML 套件 目前不支援.CSV.XLS)


匯入excel檔案,並轉換是物件List

        public List<T> ReadExcelToList<T>(string fileName, string sheetName)

        {

            List<T> dataList = new List<T>();

            Type typeObject = typeof(T);

            using (XLWorkbook work = new XLWorkbook(fileName))

            {

                var workSheet = work.Worksheets.Where(q => q.Name == sheetName).First();

                var properties = typeObject.GetProperties();

                var colums = workSheet.FirstRow().Cells().Select((v, i) => new { Value = v.Value, Index = i + 1 });

                foreach (IXLRow row in workSheet.RowsUsed().Skip(1))

                {

                    T obj = (T)Activator.CreateInstance(typeObject); 

                    foreach (var prop in properties)

                    {

                        int colIndex = colums.SingleOrDefault(c => c.Value.ToString() == prop.Name.ToString()).Index;

                        var val = row.Cell(colIndex).Value;

                        var type = prop.PropertyType;

                        prop.SetValue(obj, Convert.ChangeType(val, type));

                    } 

                    dataList.Add(obj);

                }

            } 

            return dataList;

        }



二、NPOI 支援.XLS、.XLSX

    public List<T> ReadExcelToListForXLS<T>(string fileName)

        {

            try

            {

                List<T> dataList = new List<T>();

                Type typeObject = typeof(T); 

                IWorkbook workbook = null;  //新建IWorkbook物件

                FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

                workbook = new HSSFWorkbook(fileStream);  //xlsx資料讀入workbook

                ISheet sheet = workbook.GetSheetAt(0);  //獲取第一個工作表 

                // 建立一個空的 List<string> 用來儲存轉換後的資料

                var properties = typeObject.GetProperties();

                var colums = sheet.GetRow(0).Cells.Select((v, i) => new { Value = v.StringCellValue, Index = i });

                IRow row; //新建當前工作表行資料

                for (int i = 1; i <= sheet.LastRowNum + 1; i++)  //對工作表每一行

                {

                    row = sheet.GetRow(i);   //row讀入第i行資料

                    if (row != null)

                    {

                        T obj = (T)Activator.CreateInstance(typeObject); 

                        foreach (var prop in properties)

                        {

                            int colIndex = colums.SingleOrDefault(c => c.Value.ToString() == prop.Name.ToString()).Index;

                            var val = row.GetCell(colIndex);

                            var type = prop.PropertyType;

                            prop.SetValue(obj, Convert.ChangeType(val?.ToString(), type));

                        }

                        dataList.Add(obj);

                    }

                } 

                return dataList;

            }

            catch (Exception ex)

            {

                throw ex;

            }

        }



三、CSV的匯入

  public List<T> ReadExcelToListForCSV<T>(string fileName)

        {

            try

            {

                List<T> dataList = new List<T>();

                Type typeObject = typeof(T);

                var contents = File.ReadAllText(fileName, Encoding.GetEncoding("Big5")).Split('\n');

                var csv = from line in contents

                          select line.Split(',').ToArray();

 

                var properties = typeObject.GetProperties();

                var colums = csv.ToList().First().Select((v, i) => new { Value = v.ToString().Replace("\r", string.Empty), Index = i });

                 foreach (var row in csv.Skip(1).ToList())

                {

                    T obj = (T)Activator.CreateInstance(typeObject); 

                    foreach (var prop in properties)

                    {

                        int colIndex = colums.SingleOrDefault(c => c.Value.ToString() == prop.Name.ToString()).Index;

                        var val = row[colIndex];

                        var type = prop.PropertyType;

                        prop.SetValue(obj, Convert.ChangeType(val?.ToString(), type));

                    }

                    dataList.Add(obj);

                } 

                return dataList;

            }

            catch (Exception ex)

            {

                throw ex;

            }

        }




2023年1月3日 星期二

D3.JS 長條圖範例


D3 是客製化的圖表加上動態的生動的圖表,讓人更賞心稅目,但也聽說入手不易,常常搞不懂有哪些API 可以使用,官方文件有些難閱讀等等,線上總是有很多高手有提供範利,其中我也是以新手的身份來掀開d3這神祕的面紗吧! 參考範例來源

https://gist.github.com/kurotanshi/949bc9cc6e53a2518bdedb438be0de79 

一、 引用d3的js 要引用d3要注意版本喔,不一定相容舊的版本… 

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>

二、 新增svg的畫布

 <div id="content">
   <svg class="svg"></svg>
</div>

 三、 資料收集 (要用json格式,才可以用在d3的圖表上) 

 
 var data = [
  {
    "region": "台北",
    "unit": 46.40977922,
    "price": 91086.0211,
    "unit_price": 2570.210781
  },
  {
    "region": "高雄",
    "unit": 32.4142328,
    "price": 63651.00159,
    "unit_price": 2173.609712
  },
  {
    "region": "台中",
    "unit": 29.51372024,
    "price": 69658.03571,
    "unit_price": 2125.218562
  },
  {
    "region": "彰化",
    "unit": 34.4416108,
    "price": 73852.80682,
    "unit_price": 1970.313951
  },
  {
    "region": "南投",
    "unit": 26.92638889,
    "price": 48446.94739,
    "unit_price": 1893.854422
  },
  {
    "region": "新竹",
    "unit": 43.1695172,
    "price": 85949.14021,
    "unit_price": 1813.571443
  },
  {
    "region": "花蓮",
    "unit": 31.25626667,
    "price": 50813.33333,
    "unit_price": 1694.577185
  },
  {
    "region": "台北市",
    "unit": 39.56244844,
    "price": 63101.91847,
    "unit_price": 1655.043669
  },
  {
    "region": "新北市",
    "unit": 33.11200327,
    "price": 47315.73129,
    "unit_price": 1501.26019
  },
  {
    "region": "宜蘭",
    "unit": 36.26450183,
    "price": 48655.03391,
    "unit_price": 1489.35871
  },
  {
    "region": "花蓮",
    "unit": 42.60729097,
    "price": 55846.34104,
    "unit_price": 1427.583885
  },
  {
    "region": "雲林",
    "unit": 37.96167857,
    "price": 44534.22619,
    "unit_price": 1293.030994
  }
];

 四、 宣告svg 畫布的大小範圍

使用 translate 可以讓圖形在 x 軸或 y 軸進行位移 ( 中括號為不是必須的值 ),所謂的位移是指原本的坐標加上多少。

var svg = d3.select('.svg');
 
  var margin = 80,
      width = 960 - margin * 0.7,
      height = 500 - margin * 2-30;
   
  svg.attr({
    "width": width + margin,
    "height": height + margin * 2,
    "transform": "translate(" + margin + "," + margin + ")"
  });    

 linear 意即會有等比例的縮放大小

.domain 輸入的資料來源 (0, N)
.range   
輸出的資料範圍(0,N) 

白話文的意思~ 如果你的資料來源介於(0,990) , 但輸出的數值範圍(0,100), d3的函數就會自動把值等比例的縮小至(0~100)的區間喔


var xScale_price = d3.scale.linear()
    .domain([0, data.length])
    .range([0, width]);
 
  // y 軸比例尺 2 繪製座標軸用
  var yScale2_price = d3.scale.linear()
    .domain([0, 100000])
    .range([height, 0]);

Asix : 繪製刻線
.scale    
比例尺
.orient  畫線的位置  (top  bottom   left  rieght )
.ticks     刻度的數量
.tickFormat : 設定資料格式 / 顯示刻度

 // x 軸
  var xAxis = d3.svg.axis()
    .scale(xScale_price)
    .orient("bottom")    
    .ticks( data.length )
    .tickFormat(function(i){      
      return (data[i]) ?  data[i].region : '';   // 這裡控制坐標軸的單位
    });

  // y 軸
  var yAxis = d3.svg.axis()
    .scale(yScale2_price)
    .orient("left");

新增的dom元件,將圖表繪製上畫面上

// 繪製 x 軸
  svg.append("g")
    .attr({
      "class": "x axis",
      "transform": "translate(" + margin + "," + (height + margin) + ")",
      'fill': '#ffffff'
    })
    .call(xAxis);

      // 繪製 y 軸
  svg.append("g")
    .attr({
      "class": "y axis",
      "transform": "translate(" + margin + ", " + margin + ")",
      'fill': '#ffffff'
    })
    .call(yAxis);

scale.category10   產生隨機10種顏色
selectAll                選擇dom元素 (像css語法)
data                        輸入資料來源
enter                      找出不夠資料塞入的元素筆數,再透過 append() 函式新增元素
append                   加上長方條(rect)
classed                   客製化的css 或傳入值控制css




    var xScale = d3.scale.linear().domain([0, data.length]).range([0, width]);
    var yScale  = d3.scale.linear().domain([0, 100000]).range([0, height]);
    var chartType = "price";
    var c10 = d3.scale.category10();
       // 產生長條圖
       svg.selectAll('.bar')
        .data(data)
        .enter()
        .append('rect')
        .classed('bar', true);

        svg.selectAll('.bar')
        .transition()
        .duration(700)
        .attr({
          'x': function(d, i) {
            return xScale(i) + margin
          },
          'y': function(d, i) {
            return height - yScale(d[chartType])+ margin;
          },
          'width': '5%',
          'height': function(d, i) {
            return yScale(d[chartType]);
          },
          'fill': function(d, i){
            return c10(i);
          },
          "transform": "translate(" +  width * (0.02) + ", " + 0 + ")",
        });


示易圖