# CSV轉檔程式
## 準備工作
1. 安裝 Visual Studio 開發環境
2. 下載並安裝 .NET Core SDK[下載連結](https://dotnet.microsoft.com/en-us/download)
3. 準備一個包含病人資料的 CSV 檔案
```CSV=
Name,Gender,BirthDate,Address,Telephone
John Doe,M,1970-05-25,123 Main St,Anytown CA 12345,+1-555-0123
Jane Smith,F,1985-11-30,456 Oak Rd,Someville VA 67890,+1-987-6543
```
4. 道專案目錄執行以下命令來建立一個新的 console 專案:
```
dotnet new console -n CsvToFhir
```
這將在名為 CsvToFhir 的文件夾中建立一個新專案,包含基本的 Program.cs 和 CsvToFhir.csproj。可把先前準備的CSV放在Program.cs這層資料夾中
5. 安裝 `CsvHelper`
```
dotnet add package CsvHelper
```
6. 將範例程式碼放入Program.cs中
## 範例程式碼(以Patient為例)
```chsrp=
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using Hl7.Fhir.Model;
using Hl7.Fhir.Serialization;
class Program
{
static void Main(string[] args)
{
// CSV檔案路徑和FHIR伺服器URL
string csvFilePath = @"data.csv";
string fhirServerUrl = "https://fhir.tcumi.com:58443/r5/fhir";
// 讀取CSV文件
string[] csvLines = File.ReadAllLines(csvFilePath);
// 解析CSV標頭
string[] headers = csvLines[0].Split(',');
// 創建FHIR資源列表
List<Patient> patients = new List<Patient>();
// 將CSV數據映射到FHIR資源
for (int i = 1; i < csvLines.Length; i++)
{
string[] values = csvLines[i].Split(',');
var patient = new Patient();
for (int j = 0; j < headers.Length; j++)
{
switch (headers[j].ToLower())
{
case "name":
var names = new List<HumanName>();
names.Add(new HumanName { Text = values[j] });
patient.Name = names;
break;
case "gender":
patient.Gender = values[j] == "M" ? AdministrativeGender.Male : AdministrativeGender.Female;
break;
case "birthdate":
patient.BirthDate = values[j];
break;
case "address":
patient.Address.Add(new Address { Text = values[j] });
break;
case "telephone":
patient.Telecom.Add(new ContactPoint { System = ContactPoint.ContactPointSystem.Phone, Value = values[j] });
break;
}
}
patients.Add(patient);
}
// 序列化FHIR資源
var fhirSerializer = new FhirJsonSerializer(new SerializerSettings
{
Pretty = true
});
// POST到FHIR伺服器
var client = new HttpClient();
foreach (var patient in patients)
{
patient.Id = null;
var body = fhirSerializer.SerializeToString(patient);
var response = client.PostAsync($"{fhirServerUrl}/Patient", new StringContent(body, Encoding.UTF8, "application/fhir+json")).Result;
if (response.IsSuccessStatusCode)
{
var content = response.Content.ReadAsStringAsync().Result;
Console.WriteLine($"Patient 上傳成功,回應內容:");
Console.WriteLine(content);
}
else
{
var errorContent = response.Content.ReadAsStringAsync().Result;
Console.WriteLine($"錯誤: {response.StatusCode} - {response.ReasonPhrase}");
Console.WriteLine(errorContent);
}
}
// 獲取最近上傳的Patient資源
var getResponse = client.GetAsync($"{fhirServerUrl}/Patient?_count=1").Result;
if (getResponse.IsSuccessStatusCode)
{
var getContent = getResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine("最近上傳的Patient資源:");
Console.WriteLine(getContent);
}
else
{
Console.WriteLine($"獲取Patient資源失敗: {getResponse.StatusCode} - {getResponse.ReasonPhrase}");
}
}
}
```
9. 將 `csvFilePath` 變數的值替換為專案的 CSV 檔案路徑。
10. 將 `fhirServerUrl` 變數的值替換為專案的 FHIR 伺服器的基礎 URL。
11. 建置專案
```
dotnet build
```
13. 運行專案
```
dotnet run
```
14. 執行結果


# 變更ressource方法
## 接下來會說明如何將這份程式的resource改成observation
- 以下是需要調整的地方


## 完整程式碼範例
```cshrp=
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
class Program
{
static void Main(string[] args)
{
// CSV檔案路徑和FHIR伺服器URL
string csvFilePath = @"observations.csv";
string fhirServerUrl = "https://fhir.tcumi.com:58443/r5/fhir";
// 讀取CSV文件
string[] csvLines = File.ReadAllLines(csvFilePath);
// 解析CSV標頭
string[] headers = csvLines[0].Split(',');
// 創建Observation資源列表
List<Dictionary<string, object>> observations = new List<Dictionary<string, object>>();
// 將CSV數據映射到Observation資源
for (int i = 1; i < csvLines.Length; i++)
{
string[] values = csvLines[i].Split(',');
var observation = new Dictionary<string, object>();
// 添加resourceType屬性
observation["resourceType"] = "Observation";
for (int j = 0; j < headers.Length; j++)
{
switch (headers[j].ToLower())
{
case "code":
observation["code"] = new Dictionary<string, object>
{
["coding"] = new List<Dictionary<string, string>>
{
new Dictionary<string, string>
{
["system"] = "http://loinc.org",
["code"] = values[j]
}
}
};
break;
case "value":
observation["valueQuantity"] = new Dictionary<string, object>
{
["value"] = double.Parse(values[j]),
["unit"] = "mg/dL",
["system"] = "http://unitsofmeasure.org",
["code"] = "mg/dL"
};
break;
case "date":
observation["effectiveDateTime"] = values[j];
break;
case "subject":
observation["subject"] = new Dictionary<string, string>
{
["reference"] = $"Patient/{values[j]}"
};
break;
}
}
observations.Add(observation);
}
// 序列化Observation資源
var options = new JsonSerializerOptions { WriteIndented = true };
// POST到FHIR伺服器
var client = new HttpClient();
foreach (var observation in observations)
{
var body = JsonSerializer.Serialize(observation, options);
var response = client.PostAsync($"{fhirServerUrl}/Observation", new StringContent(body, Encoding.UTF8, "application/fhir+json")).Result;
if (response.IsSuccessStatusCode)
{
var content = response.Content.ReadAsStringAsync().Result;
Console.WriteLine($"Observation 上傳成功,回應內容:");
Console.WriteLine(content);
}
else
{
var errorContent = response.Content.ReadAsStringAsync().Result;
Console.WriteLine($"錯誤: {response.StatusCode} - {response.ReasonPhrase}");
Console.WriteLine(errorContent);
}
}
// 獲取最近上傳的Observation資源
var getResponse = client.GetAsync($"{fhirServerUrl}/Observation?_count=1").Result;
if (getResponse.IsSuccessStatusCode)
{
var getContent = getResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine("最近上傳的Observation資源:");
Console.WriteLine(getContent);
}
else
{
Console.WriteLine($"獲取Observation資源失敗: {getResponse.StatusCode} - {getResponse.ReasonPhrase}");
}
}
}
```