HttpClient(C#)

Web系を開発していると動作をトレースするためにHttpクライアントが必要な場合があります。


using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace HttpClientSim
{

    class HttpClientSim
    {
        public static HttpResponseMessage PostJson(string url, Dictionary<string, string> headers, Dictionary<string, string> querys,string json, ProxyInfo info)
        {
            HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, url);

            // request header

            foreach (KeyValuePair<string, string> pair in headers)
            {
                req.Headers.Add(pair.Key, pair.Value);
            }

            // query string

            Uri uri = null;

            if (querys != null)
            {
                var query = HttpUtility.ParseQueryString("");

                foreach (KeyValuePair<string, string> pair in querys)
                {
                    query.Add(pair.Key, pair.Value);
                }

                var builder = new UriBuilder(url);
                builder.Query = query.ToString();
                uri = builder.Uri;
            }
            else
            {
                var builder = new UriBuilder(url);
                uri = builder.Uri;
            }

            // json content

            if (json == null) json = "";

            StringContent jsonContent = new StringContent(json, Encoding.UTF8, "application/json");

            using (HttpClientHandler handler = new HttpClientHandler())
            {

                // no verify

                handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
                {
                    return true;
                };

                // proxy

                if (info != null)
                {
                    handler.Proxy = new WebProxy(info.Url);
                    handler.Credentials = new NetworkCredential(info.Id, info.Pass);
                    handler.UseProxy = true;
                }

                // request

                using (HttpClient client = new HttpClient(handler))
                {
                    Task task = client.PostAsync(uri, jsonContent);

                    return task.Result;
                }
            }
        }


        public static HttpResponseMessage Post(string url, Dictionary<string, string> headers, Dictionary<string, string> querys, Dictionary<string, string> bodys, ProxyInfo info)
        {
            HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, url);

            // request header

            foreach (KeyValuePair<string, string> pair in headers)
            {
                req.Headers.Add(pair.Key, pair.Value);
            }

            // query string

            Uri uri = null;

            if (querys != null)
            {
                var query = HttpUtility.ParseQueryString("");

                foreach (KeyValuePair<string, string> pair in querys)
                {
                    query.Add(pair.Key, pair.Value);
                }

                var builder = new UriBuilder(url);
                builder.Query = query.ToString();
                uri = builder.Uri;
            }
            else
            {
                var builder = new UriBuilder(url);
                uri = builder.Uri;
            }

            // body content

            if (bodys == null) bodys = new Dictionary<string, string>();

            var formContent = new FormUrlEncodedContent(bodys);

            using (HttpClientHandler handler = new HttpClientHandler())
            {

                // no verify

                handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
                {
                    return true;
                };

                // proxy

                if (info != null)
                {
                    handler.Proxy = new WebProxy(info.Url);
                    handler.Credentials = new NetworkCredential(info.Id, info.Pass);
                    handler.UseProxy = true;
                }

                // request

                using (HttpClient client = new HttpClient(handler))
                {
                    Task task = client.PostAsync(uri, formContent);

                    return task.Result;
                }
            }
        }
    }


    class ProxyInfo
    {
        public string Url { get; }

        public string Id { get; }

        public string Pass { get; }

        public ProxyInfo(string url,string id,string pass)
        {
            if(url == null || id == null || pass == null)
            {
                throw new ArgumentException("引数不正");
            }

            this.Url = url;
            this.Id = id;
            this.Pass = pass;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://localhost:3000/aa";
            var bodys = "{\"aa\":\"bbbbb\",\"dddsa\":\"deee\"}";

            var qs = new Dictionary<string, string>();
            qs.Add("ffff", "ggg g");

            var res = HttpClientSim.PostJson(url, new Dictionary<string, string>(), qs, bodys, null);

            Console.WriteLine(res.StatusCode);
        }
    }
}


Excelを読み込んで他の言語で読めるようにテキストに出力する(powershell)

よく客先常駐等で勝手にOSS入れられない等不便な場合があります。かといってVBAは文法使いにくし、JScript.netを今さらやる気も出ない。Powershellならデフォで入っているが、遅いから他の言語向けに中身だけ抽出したいということがあるかもしれません。

  1. 環境はWindows10/PS5.1。
  2. Excelのセルを他で読めるようにテキストに出す。
  3. ExcelのセルはA1から末端までとします。

$error.Clear()
if($args.Length -ne 2) {
    Write-Host "./excelsample.ps1 excelfile(fullpath) outputfile"
    Exit(9)
}

if((Test-Path $args[0] -PathType Leaf) -eq $false) {
    Write-Host "file not found:${$args[0]}"
}

$exl = $null
$book = $null

$append = $false

try {
    $exl = New-Object -com Excel.Application
    $exl.Visible = $false
    $exl.DisplayAlerts = $false

    $book = $exl.Workbooks.Open($args[0],0,$true)

    foreach($sheet in $book.Worksheets) {
        Write-Host $sheet.Name

        $usedrange = $sheet.UsedRange.Address()
        $allrange = ""
        if($usedrange.IndexOf(":") -eq - 1) {
            $allrange = "`$A`$1:" + $usedrange
        } else {
            $allrange = "`$A`$1:" + $usedrange.Split(':')[1]
        }

        $cells = $sheet.Range($allrange).Value()

        $sw = New-Object System.IO.StreamWriter($args[1], $append, [Text.Encoding]::GetEncoding("UTF-8"))

        $sw.WriteLine("sheet," + $sheet.Name)
        for($r = 1;$r -le $cells.GetLength(0);$r++) {
            for($c = 1;$c -le $cells.GetLength(1);$c++) {
                $line = "$r,$c," + $cells[$r,$c].Length + "," + $cells[$r,$c]
                $sw.WriteLine($line)
            }
        }

        $sw.Close()

        $append = $true

        [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet) > $null
        $sheet = $null
    }
}
finally {
    if($book -ne $null) {
        $book.Close()
        [System.Runtime.Interopservices.Marshal]::ReleaseComObject($book) > $null
        $book = $null
    }
    if($exl -ne $null) {
        $exl.Quit()
        [System.Runtime.Interopservices.Marshal]::ReleaseComObject($exl) > $null
        $exl = $null
    }
    [System.GC]::Collect()

    if($error.Count -ne 0) {
        Write-Host $error
        Exit(9)
    }
}


Excelを読み込んで2次元リストにする(python)

色々作業をする時にExcelを読み込む必要があるケースが多いです。一括して読み込んでおくライブラリがあれば便利です。

  1. 環境はanaconda3。
  2. 2次元リストは全て文字列で、シート名をキーとした辞書型で返却する。
    Dict[str,List[List[str]]]
  3. Excelのセルの表示形式は「文字列」前提とします。

from typing import List,Dict
import xlrd
import os.path
from datetime import datetime,timedelta

def book_dict_ary(xl_path:str) -> Dict[str,List[List[str]]]:
    """
    xlsxファイルをシート名をキーにした2次元リストを作成する。

    Parameters
    ----------
    xl_path : str
        xlsxファイルのパス
        xlsxファイルの表示形式は"文字列"限定
    
    Returns
    -------
    book_dict : Dict[str,List[List[str]]]
        シート名をキーとしたセルの2次元リストs
        セルはすべてstr型
    """

    # 引数チェック
    if xl_path == None:
        raise Exception('引数不正:None')

    if not os.path.isfile(xl_path):
        raise FileNotFoundError('ファイルが存在しない:' + xl_path)
    
    # bookを開く
    book = xlrd.open_workbook(xl_path)
    
    # 辞書作成
    return {sheet_name: sheet_cells_ary(book.sheet_by_name(sheet_name)) for sheet_name in book.sheet_names()}

def sheet_cells_ary(sheet:xlrd.sheet) -> List[List[str]]:
    """
    引数に指定されたシートを2次元配リストにする。

    Parameters
    ----------
    sheet : xlrd.sheet
        2次元リストにするシート。

    Returns
    -------
    cells : List[List[str]]
        2次元リスト
    """

    return [[cell.value for cell in rows] for rows in sheet.get_rows()]

def _cell_value_to_str(cell:xlrd.sheet.Cell) -> str:
    if cell == None or cell.ctype == xlrd.XL_CELL_EMPTY or cell.ctype == xlrd.XL_CELL_ERROR or cell.ctype == xlrd.XL_CELL_BLANK:
        return ""
    elif cell.ctype == xlrd.XL_CELL_TEXT:
        return cell.value
    elif cell.ctype == xlrd.XL_CELL_NUMBER or cell.ctype == xlrd.XL_CELL_BOOLEAN:
        return str(cell.value)
    elif cell.ctype == xlrd.XL_CELL_DATE:
        return str(datetime(1899,12,30) + timedelta(days=cell.value))
        

if __name__ == "__main__":
    tmp = book_dict_ary('sample.xlsx')
    print(tmp)