ibms-MCUT/FrontendWebApi/ApiControllers/HydroMeterController.cs
jiahao 0eed71c0a4 1.bgService歸檔服務-改為補償機制
2.前台 api :棟別名稱修正、檔案下載修正
2023-09-24 20:44:30 +08:00

1418 lines
73 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FrontendWebApi.Models;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MySqlX.XDevAPI;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Repository.BackendRepository.Interface;
using Repository.FrontendRepository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Ionic.Zip;
using System.Collections.Immutable;
using System.Text;
using iTextSharp.text;
using System.Collections;
using Google.Protobuf.Collections;
using Org.BouncyCastle.Asn1.Pkcs;
using NPOI.SS.Formula.Functions;
using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData;
namespace FrontendWebApi.ApiControllers
{
public class HydroMeterController : MyBaseApiController<HydroMeterController>
{
private readonly IBackendRepository backendRepository;
private readonly IFrontendRepository frontendRepository;
private ICellStyle greencellstyle;
public HydroMeterController(IBackendRepository backendRepository, IFrontendRepository frontendRepository)
{
this.backendRepository = backendRepository;
this.frontendRepository = frontendRepository;
}
/// <summary>
/// 電表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
[Route("api/ElectricList")]
public async Task<ActionResult<ApiResult<List<HydroMeterOutput>>>> ElectricList([FromBody] HydroMeterInput input)
{
ApiResult<List<HydroMeterOutput>> apiResult = new ApiResult<List<HydroMeterOutput>>(jwt_str);
if (!jwtlife)
{
apiResult.Code = "5000";
return BadRequest(apiResult);
}
string tableType = "day week month year";
if (input.building_tag == null)
{
apiResult.Code = "9999";
apiResult.Msg = "棟別沒有被選取";
return BadRequest(apiResult);
}
else if (input.tableType == null || !tableType.Contains(input.tableType))
{
apiResult.Code = "9999";
apiResult.Msg = "表單類別錯誤";
return BadRequest(apiResult);
}
//else if (input.floor_tag.Count == 0)
//{
// apiResult.Code = "0000";
// apiResult.Data = new List<HydroMeterOutput>() { };
// return Ok(apiResult);
//}
try
{
var startTime = input.tableType == "day" || input.tableType == "week"
? input.startTime + "-01"
: input.tableType == "month" || input.tableType == "year" ? input.startTime + "-01-01"
: null;
var endTime = input.tableType == "day" || input.tableType == "week"
? input.startTime.Split("-")[0] + "-" + (Int32.Parse(input.startTime.Split("-")[1]) + 1).ToString().PadLeft(2, '0') + "-01"
: input.tableType == "month" ? (Int32.Parse(input.startTime.Split("-")[0]) + 1) + "-01-01"
: input.tableType == "year" ? (Int32.Parse(input.endTime) + 1).ToString() + "-01-01"
: null;
string sqlWhere = "";
string sqlGroup = "";
string sqlAvgRawData = "";
string dbDateName = startTime.Split("-")[0].ToString().PadLeft(4, '0') + startTime.Split("-")[1].ToString().PadLeft(2, '0');
string buildingSql = "";
string tag_quantity = await backendRepository.GetOneAsync<string>("select system_value from variable where system_type = 'obixConfig' and system_key = 'tag_quantity' and deleted = 0");
string[] parts_buildingTag = input.building_tag.Split(',');
StringBuilder fix_buildingTag = new StringBuilder();
foreach (string part in parts_buildingTag)
{
fix_buildingTag.Append("'").Append(part.Trim()).Append("', ");
}
input.building_tag = fix_buildingTag.ToString().TrimEnd(',', ' ');
if (tag_quantity == "5")
buildingSql = @$" and SUBSTRING_INDEX(device_number, '_', 1) in ({input.building_tag}) ";
else
buildingSql = @$" and SUBSTRING_INDEX(SUBSTRING_INDEX(device_number, '_', 2), '_', -1) in ({input.building_tag}) ";
//if (input.floor_tag.Count > 0)
//{
// if (tag_quantity == "5")
// sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag ";
// else
// sqlWhere = $@" and substring_index(substring_index(device_number, '_', 5), '_', -1) in @floor_tag ";
//}
if (input.tableType == "year")
{
sqlGroup = $@" group by year(start_timestamp), year(end_timestamp), device_number ";
sqlAvgRawData = " round(sum(kwh_result), 2) as avg_rawdata, year(start_timestamp) as start_timestamp, year(end_timestamp) as end_timestamp ";
}
else
sqlAvgRawData = " round(kwh_result, 2) as avg_rawdata, start_timestamp, end_timestamp ";
var table = input.tableType == "year" ? "archive_electric_meter_month" : "archive_electric_meter_" + input.tableType + (input.tableType == "day" ? "_" + dbDateName : "");
var schema = await backendRepository.GetOneAsync<string>($"select system_value from variable where system_type = 'project_name'");
var isTable = await backendRepository.GetOneAsync<string>($"select table_name from information_schema.tables where table_name = '{table}' and table_schema = '{schema.Split('/')[0]}'");
if (string.IsNullOrEmpty(isTable)) //check for has table or not
{
apiResult.Code = "0000";
apiResult.Data = new List<HydroMeterOutput>() { };
return Ok(apiResult);
}
var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null;
var aemmEndDate = input.tableType == "year" ? $"year(DATE_ADD(fd.date, INTERVAL +1 {input.tableType}))" : $"DATE_ADD(fd.date, INTERVAL +1 {input.tableType})";
var aemmStaDate = input.tableType == "year" ? "year(fd.date)" : "fd.date";
string date_yyyymmdd = "";
switch (input.tableType)
{
case "day": date_yyyymmdd = @$" date(aemm.start_timestamp) = {aemmStaDate}"; break;
case "month": date_yyyymmdd = @$" aemm.start_timestamp >= {aemmStaDate} and aemm.end_timestamp < {aemmEndDate} "; break;
case "year": date_yyyymmdd = @$" aemm.start_timestamp >= {aemmStaDate} and aemm.end_timestamp < {aemmEndDate} "; break;
}
var sql = $@"set @i = -1;
select fd.device_number, case when aemm.avg_rawdata = -1.0 then 'NaN' when aemm.avg_rawdata is null then 0.00 else aemm.avg_rawdata end as avg_rawdata, DATE_FORMAT(fd.date, @dateFormat) as timestamp
from (
select *
from (
(
SELECT DATE(ADDDATE('{startTime}', INTERVAL @i:=@i+1 {input.tableType})) AS date
FROM {table}
HAVING @i < TIMESTAMPDIFF({input.tableType}, '{startTime}', ADDDATE('{endTime}' , INTERVAL -1 DAY))
) d,
(
select device_number
from {table}
where start_timestamp >= '{startTime}' and end_timestamp < '{endTime}' and point = 'KWH' {buildingSql}
{sqlWhere}
group by device_number
) dn
)
) fd
left join (
select device_number, {sqlAvgRawData}
from {table}
where start_timestamp >= '{startTime}' and end_timestamp < '{endTime}' and point = 'KWH' {buildingSql}
{sqlWhere} {sqlGroup}
) aemm on {date_yyyymmdd} and aemm.device_number = fd.device_number
join device dc on fd.device_number = dc.device_number
where dc.deleted = 0
order by fd.device_number, fd.date";
Logger.LogInformation("0918 SQL = " + sql + Environment.NewLine + " startTime='" + startTime + "' endTime='" + endTime + "' building=" + input.building_tag );
var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataOutput>(sql,
new { startTime = startTime, endtime = endTime, building_tag = input.building_tag, dateFormat = dateFormat });
List<HydroMeterOutput> list = new List<HydroMeterOutput>();
if (tag_quantity == "5")
{
list = rawData
.GroupBy(x => new { building_tag = x.device_number.Split("_")[0], floor_tag = x.device_number.Split("_")[2], device_serial_tag = x.device_number.Split("_")[4], device_number = x.device_number })
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag, device_number = x.Key.device_number })
.ToList();
}
else
{
list = rawData
.GroupBy(x => new { building_tag = x.device_number.Split("_")[1], floor_tag = x.device_number.Split("_")[4], device_master = x.device_number.Split("_")[5], device_serial_tag = x.device_number.Split("_")[7], device_number = x.device_number })
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag, device_master = x.Key.device_master, device_number = x.Key.device_number })
.ToList();
}
int i = 0;
foreach (var l in list)
{
l.rawData = new List<HydroMeterRawDataOutput>();
l.device_full_name = await backendRepository.GetOneAsync<string>($"select full_name from device where device_number = '{l.device_number}'");
if (tag_quantity == "5")
{
l.rawData.AddRange(
rawData.Where(x => x.device_number.Split("_")[0] == l.building_tag && x.device_number.Split("_")[2] == l.floor_tag && x.device_number.Split("_")[4] == l.device_serial_tag)
);
}
else
{
l.rawData.AddRange(
rawData.Where(x => x.device_number.Split("_")[1] == l.building_tag && x.device_number.Split("_")[4] == l.floor_tag && x.device_number.Split("_")[5] == l.device_master && x.device_number.Split("_")[7] == l.device_serial_tag )
);
}
l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
new { building_tag = l.building_tag });
l.total = l.rawData.Where(x => x.avg_rawdata != "NaN").Sum(x => decimal.Parse(x.avg_rawdata ?? "0", System.Globalization.NumberStyles.Float)).ToString();
l.price = input.price.HasValue
? (Math.Round(input.price.Value, 2)).ToString()
: Math.Round((await backendRepository.GetOneAsync<decimal>("select system_value from variable where system_type = 'ElectricPrice' and deleted = 0")), 2).ToString();
l.total_price = Math.Round((Decimal.Parse(l.total) * Decimal.Parse(l.price)), 2).ToString();
i++;
}
Logger.LogInformation(" 筆數:" + i.ToString());
apiResult.Code = "0000";
apiResult.Data = list;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(input);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 水表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
[Route("api/WaterList")]
public async Task<ActionResult<ApiResult<List<HydroMeterOutput>>>> WaterList([FromBody] HydroMeterInput input)
{
ApiResult<List<HydroMeterOutput>> apiResult = new ApiResult<List<HydroMeterOutput>>(jwt_str);
if (!jwtlife)
{
apiResult.Code = "5000";
return BadRequest(apiResult);
}
string tableType = "day week month year";
if (input.building_tag == null)
{
apiResult.Code = "9999";
apiResult.Msg = "棟別沒有被選取";
return BadRequest(apiResult);
}
else if (input.tableType == null || !tableType.Contains(input.tableType))
{
apiResult.Code = "9999";
apiResult.Msg = "表單類別錯誤";
return BadRequest(apiResult);
}
else if (input.floor_tag.Count == 0)
{
apiResult.Code = "0000";
apiResult.Data = new List<HydroMeterOutput>() { };
return Ok(apiResult);
}
try
{
var startTime = input.tableType == "day" || input.tableType == "week"
? input.startTime + "-01"
: input.tableType == "month" || input.tableType == "year" ? input.startTime + "-01-01"
: null;
var endTime = input.tableType == "day" || input.tableType == "week"
? input.startTime.Split("-")[0] + "-" + (Int32.Parse(input.startTime.Split("-")[1]) + 1).ToString().PadLeft(2, '0') + "-01"
: input.tableType == "month" ? (Int32.Parse(input.startTime.Split("-")[0]) + 1) + "-01-01"
: input.tableType == "year" ? (Int32.Parse(input.endTime) + 1).ToString() + "-01-01"
: null;
string dbDateName = startTime.Split("-")[0].ToString().PadLeft(4, '0') + startTime.Split("-")[1].ToString().PadLeft(2, '0');
string sqlWhere = "";
string sqlGroup = "";
string sqlAvgRawData = "";
string buildingSql = "";
string tag_quantity = await backendRepository.GetOneAsync<string>("select system_value from variable where system_type = 'obixConfig' and system_key = 'tag_quantity' and deleted = 0");
if (tag_quantity == "5")
buildingSql = " and SUBSTRING_INDEX(device_number, '_', 1) in (@building_tag) ";
else
buildingSql = " and SUBSTRING_INDEX(SUBSTRING_INDEX(device_number, '_', 2), '_', -1) in (@building_tag) ";
if (input.floor_tag.Count > 0)
{
if (tag_quantity == "5")
sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag ";
else
sqlWhere = $@" and substring_index(substring_index(device_number, '_', 5), '_', -1) in @floor_tag ";
}
if (input.tableType == "year")
{
sqlGroup = $@" group by year(start_timestamp), year(end_timestamp), device_number ";
sqlAvgRawData = " round(avg(avg_rawdata), 2) as avg_rawdata, year(start_timestamp) as start_timestamp, year(end_timestamp) as end_timestamp ";
}
else
sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata, start_timestamp, end_timestamp ";
var table = input.tableType == "year" ? "archive_electric_meter_month" : "archive_electric_meter_" + input.tableType + (input.tableType == "day" ? "_" + dbDateName : "");
var schema = await backendRepository.GetOneAsync<string>($"select system_value from variable where system_type = 'project_name'");
var isTable = await backendRepository.GetOneAsync<string>($"select table_name from information_schema.tables where table_name = '{table}' and table_schema = '{schema.Split('/')[0]}'");
if (string.IsNullOrEmpty(isTable)) //check for has table or not
{
apiResult.Code = "0000";
apiResult.Data = new List<HydroMeterOutput>() { };
return Ok(apiResult);
}
var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null;
var aemmEndDate = input.tableType == "year" ? $"year(DATE_ADD(fd.date, INTERVAL +1 {input.tableType}))" : $"DATE_ADD(fd.date, INTERVAL +1 {input.tableType})";
var aemmStaDate = input.tableType == "year" ? "year(fd.date)" : "fd.date";
var sql = $@"set @i = -1;
select fd.device_number, case when aemm.avg_rawdata = -1 then 'NaN' when aemm.avg_rawdata is null then 0.00 else aemm.avg_rawdata end as avg_rawdata, DATE_FORMAT(fd.date, @dateFormat) as timestamp
from (
select *
from (
(
SELECT DATE(ADDDATE(@startTime, INTERVAL @i:=@i+1 {input.tableType})) AS date
FROM {table}
HAVING @i < TIMESTAMPDIFF({input.tableType}, @startTime, ADDDATE(@endTime, INTERVAL -1 DAY))
) d,
(
select device_number
from {table}
where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' {buildingSql}
{sqlWhere}
group by device_number
) dn
)
) fd
left join (
select device_number, {sqlAvgRawData}
from {table}
where start_timestamp >= {aemmStaDate} and end_timestamp < {aemmEndDate} and point = 'RCV' {buildingSql}
{sqlWhere} {sqlGroup}
) aemm on aemm.start_timestamp >= fd.date and aemm.end_timestamp < DATE_ADD(fd.date, INTERVAL +1 {input.tableType}) and aemm.device_number = fd.device_number
order by fd.device_number, fd.date";
var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataOutput>(sql,
new { startTime = startTime, endTime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat });
List<HydroMeterOutput> list = new List<HydroMeterOutput>();
if (tag_quantity == "5")
{
list = rawData
.GroupBy(x => new { building_tag = x.device_number.Split("_")[0], floor_tag = x.device_number.Split("_")[2], device_serial_tag = x.device_number.Split("_")[4], device_number = x.device_number })
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag, device_number = x.Key.device_number })
.ToList();
}
else
{
list = rawData
.GroupBy(x => new { building_tag = x.device_number.Split("_")[1], floor_tag = x.device_number.Split("_")[4], device_master = x.device_number.Split("_")[5], device_serial_tag = x.device_number.Split("_")[7], device_number = x.device_number })
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag, device_master = x.Key.device_master, device_number = x.Key.device_number })
.ToList();
}
foreach (var l in list)
{
l.rawData = new List<HydroMeterRawDataOutput>();
l.device_full_name = await backendRepository.GetOneAsync<string>($"select full_name from device where device_number = '{l.device_number}'");
if (tag_quantity == "5")
{
l.rawData.AddRange(
rawData.Where(x => x.device_number.Split("_")[0] == l.building_tag && x.device_number.Split("_")[2] == l.floor_tag && x.device_number.Split("_")[4] == l.device_serial_tag)
);
}
else
{
l.rawData.AddRange(
rawData.Where(x => x.device_number.Split("_")[1] == l.building_tag && x.device_number.Split("_")[4] == l.floor_tag && x.device_number.Split("_")[5] == l.device_master && x.device_number.Split("_")[7] == l.device_serial_tag)
);
}
l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
new { building_tag = l.building_tag });
l.total = l.rawData.Where(x => x.avg_rawdata != "NaN").Sum(x => decimal.Parse(x.avg_rawdata, System.Globalization.NumberStyles.Float)).ToString();
l.price = input.price.HasValue
? (Math.Round(input.price.Value, 2)).ToString()
: Math.Round((await backendRepository.GetOneAsync<decimal>("select system_value from variable where system_type = 'WaterPrice' and deleted = 0")), 2).ToString();
l.total_price = Math.Round((Decimal.Parse(l.total) * Decimal.Parse(l.price)), 2).ToString();
}
apiResult.Code = "0000";
apiResult.Data = list;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(input);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 水電表費用
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
[Route("api/HydroMeterPrice")]
public async Task<ActionResult<ApiResult<decimal>>> Price([FromBody] HydroMeterPriceInput input)
{
ApiResult<decimal> apiResult = new ApiResult<decimal>(jwt_str);
if (!jwtlife)
{
apiResult.Code = "5000";
return BadRequest(apiResult);
}
try
{
apiResult.Code = "0000";
apiResult.Data = await backendRepository.GetOneAsync<decimal>($@"select system_value from variable where system_type = '{input.type}Price' and deleted = 0");
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(input);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
[Route("api/ExportElectricList")]
public FileResult OpeExportExcelElec([FromBody] HydroMeterInput input)
{
List<List<HydroMeterOutput>> result = new List<List<HydroMeterOutput>>();
var building = backendRepository.GetAllAsync<HydroBuildList>("select * from building where deleted = 0").Result;
foreach(var b in building)
{
input.building_tag = b.building_tag;
result.Add(this.ElectricList(input).Result.Value.Data.ToList());
}
List<Dictionary<string, byte[]>> docFile = new List<Dictionary<string, byte[]>>();
var workbook = new XSSFWorkbook();
#region excel設定
IFont font12 = workbook.CreateFont();
font12.FontName = "新細明體";
font12.FontHeightInPoints = 12;
ICellStyle style12 = workbook.CreateCellStyle();
style12.SetFont(font12);
style12.Alignment = HorizontalAlignment.Center;
style12.VerticalAlignment = VerticalAlignment.Center;
IFont font12Times = workbook.CreateFont();
font12Times.FontName = "Times New Roman";
font12Times.FontHeightInPoints = 12;
IFont font18 = workbook.CreateFont();
font18.FontName = "新細明體";
font18.FontHeightInPoints = 18;
font18.IsBold = true;
ICellStyle styleTitle18 = workbook.CreateCellStyle();
styleTitle18.SetFont(font18);
styleTitle18.Alignment = HorizontalAlignment.Center;
styleTitle18.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLeft12 = workbook.CreateCellStyle();
styleLeft12.SetFont(font12);
styleLeft12.Alignment = HorizontalAlignment.Left;
styleLeft12.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLine12 = workbook.CreateCellStyle();
styleLine12.SetFont(font12);
styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
styleLine12.VerticalAlignment = VerticalAlignment.Center;
styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
#region setting for data
//IFont fontNumeric = workbook.CreateFont();
//fontNumeric.FontName = "新細明體";
//fontNumeric.FontHeightInPoints = 12;
//ICellStyle styleLineNumeric = workbook.CreateCellStyle();
//styleLineNumeric.SetFont(fontNumeric);
//styleLineNumeric.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
//styleLineNumeric.VerticalAlignment = VerticalAlignment.Center;
//styleLineNumeric.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
//styleLineNumeric.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
//styleLineNumeric.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
//styleLineNumeric.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
#endregion
ICellStyle stylein12 = workbook.CreateCellStyle();
stylein12.SetFont(font12Times);
stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
stylein12.VerticalAlignment = VerticalAlignment.Center;
stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.WrapText = true;
#endregion
foreach (var r in result)
{
if (r.Count > 0)
{
string buildingName = r.Select(x => x.building_name).FirstOrDefault();
var sheet = workbook.CreateSheet($"{buildingName}");
int RowPosition = 0;
#region set cell
IRow row = sheet.CreateRow(RowPosition);
sheet.SetColumnWidth(0, 4 * 160 * 12);
sheet.SetColumnWidth(1, 4 * 160 * 12);
sheet.SetColumnWidth(2, 4 * 160 * 12);
int i = 0;
ICell cell = row.CreateCell(i++);
cell.SetCellValue("棟別");
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue("樓層");
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue("設備");
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue("單位");
cell.CellStyle = styleLine12;
foreach (var rr in r.FirstOrDefault().rawData)
{
cell = row.CreateCell(i++);
cell.SetCellValue(rr.timeStamp);
cell.CellStyle = styleLine12;
}
cell = row.CreateCell(i++);
cell.SetCellValue("小計");
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue("單價");
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue("金額總計");
cell.CellStyle = styleLine12;
#endregion
foreach (var rr in r)
{
RowPosition += 1;
int k = 4;
row = sheet.CreateRow(RowPosition);
for (int j = 0; j <= i; j++)
{
cell = row.CreateCell(j);
if (j == 0)
{
cell.SetCellValue(rr.building_name);
}
else if (j == 1)
{
cell.SetCellValue(rr.floor_tag);
}
else if (j == 2)
{
cell.SetCellValue(rr.device_full_name);
}
else if (j == 3)
{
cell.SetCellValue("kWh");
}
else if (j == 4)
{
foreach (var rrr in rr.rawData)
{
cell.SetCellValue(rrr.avg_rawdata.ToString());
j++;
k++;
cell = row.CreateCell(j);
}
}
if (j == k)
{
cell.SetCellValue(rr.total);
}
else if (j == k+1)
{
cell.SetCellValue(rr.price);
}
else if (j == k+2)
{
cell.SetCellValue(rr.total_price);
}
cell.CellStyle = style12;
}
}
}
}
var ms = new NpoiMemoryStream
{
AllowClose = false
};
workbook.Write(ms);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return File(ms, "application/vnd.ms", @$"電表報表_{System.DateTime.Now.ToString("yyyyMMddHHmm")}.xlsx");
}
[HttpPost]
[Route("api/ExportElectricCompareList")]
public FileResult OpeExportCompareExcelElec([FromBody] List<HydroMeterInput> input)
{
List<HydroMeterOutput> result = new List<HydroMeterOutput>();
List<List<HydroMeterOutput>> result1 = new List<List<HydroMeterOutput>>();
List<List<HydroMeterOutput>> result2 = new List<List<HydroMeterOutput>>();
List<Dictionary<string, byte[]>> docFile = new List<Dictionary<string, byte[]>>();
var building = backendRepository.GetAllAsync<HydroBuildList>("select * from building where deleted = 0").Result;
foreach (var b in building)
{
input[0].building_tag = b.building_tag;
input[1].building_tag = b.building_tag;
result1.Add(this.ElectricList(input[0]).Result.Value.Data.ToList());
result2.Add(this.ElectricList(input[1]).Result.Value.Data.ToList());
}
Dictionary<string, List<string>> compareDict = new Dictionary<string, List<string>>();
var rawDataTitle = new List<string>();
if (input[0].tableType == "month")
{
for (var i = 1; i <= 12; i++)
{
rawDataTitle.Add(input[0].startTime + "-" + i.ToString().PadLeft(2, '0'));
rawDataTitle.Add(input[1].startTime + "-" + i.ToString().PadLeft(2, '0'));
}
}
else if (input[0].tableType == "day")
{
var days = GetDayInMonth(input[0].startTime);
for (var i = 1 ;i <= days ; i++) {
rawDataTitle.Add(input[0].startTime + "-" + i.ToString().PadLeft(2, '0'));
rawDataTitle.Add(input[1].startTime + "-" + i.ToString().PadLeft(2, '0'));
}
}
var workbook = new XSSFWorkbook();
#region excel設定
IFont font12 = workbook.CreateFont();
font12.FontName = "新細明體";
font12.FontHeightInPoints = 12;
ICellStyle style12 = workbook.CreateCellStyle();
style12.SetFont(font12);
style12.Alignment = HorizontalAlignment.Center;
style12.VerticalAlignment = VerticalAlignment.Center;
IFont font12Times = workbook.CreateFont();
font12Times.FontName = "Times New Roman";
font12Times.FontHeightInPoints = 12;
IFont font18 = workbook.CreateFont();
font18.FontName = "新細明體";
font18.FontHeightInPoints = 18;
font18.IsBold = true;
ICellStyle styleTitle18 = workbook.CreateCellStyle();
styleTitle18.SetFont(font18);
styleTitle18.Alignment = HorizontalAlignment.Center;
styleTitle18.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLeft12 = workbook.CreateCellStyle();
styleLeft12.SetFont(font12);
styleLeft12.Alignment = HorizontalAlignment.Left;
styleLeft12.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLine12 = workbook.CreateCellStyle();
styleLine12.SetFont(font12);
styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
styleLine12.VerticalAlignment = VerticalAlignment.Center;
styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
ICellStyle stylein12 = workbook.CreateCellStyle();
stylein12.SetFont(font12Times);
stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
stylein12.VerticalAlignment = VerticalAlignment.Center;
stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.WrapText = true;
#endregion
foreach (var b in building)
{
var res1 = result1.Where(x => x.Select(x => x.building_tag).Contains(b.building_tag)).ToList();
var res2 = result2.Where(x => x.Select(x => x.building_tag).Contains(b.building_tag)).ToList();
if (res1.Count > 0 || res2.Count > 0)
{
var sheet = workbook.CreateSheet($"{b.full_name}電表報表");
int RowPosition = 0;
result = res1.FirstOrDefault() ?? new List<HydroMeterOutput>();
var r2 = res2.FirstOrDefault() ?? new List<HydroMeterOutput>();
foreach (var r in r2)
{
var target = result.Where(x => x.building_tag == r.building_tag && x.device_serial_tag == r.device_serial_tag && x.floor_tag == r.floor_tag && x.device_number == r.device_number).FirstOrDefault();
compareDict[r.building_tag + r.floor_tag + r.device_serial_tag + r.device_number] = new List<string>() { r.total, r.price, r.total_price };
if (target != null)
{
target.rawData = target.rawData.Concat(r.rawData).ToList();
}
else
{
r.total = null;
r.price = null;
r.total_price = null;
result.Add(r);
}
}
#region set cell
IRow row = sheet.CreateRow(RowPosition);
sheet.SetColumnWidth(0, 4 * 160 * 12);
sheet.SetColumnWidth(1, 4 * 160 * 12);
sheet.SetColumnWidth(2, 4 * 160 * 12);
int i = 0;
ICell cell = row.CreateCell(i++);
cell.SetCellValue("棟別");
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue("樓層");
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue("設備");
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue("單位");
cell.CellStyle = styleLine12;
foreach (var rr in rawDataTitle)
{
sheet.SetColumnWidth(i, 2 * 160 * 12);
cell = row.CreateCell(i++);
cell.SetCellValue(rr);
cell.CellStyle = styleLine12;
}
cell = row.CreateCell(i++);
cell.SetCellValue(input[0].startTime + "小計");
sheet.SetColumnWidth(i - 1, 2 * 160 * 12);
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue(input[1].startTime + "小計");
sheet.SetColumnWidth(i - 1, 2 * 160 * 12);
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue(input[0].startTime + "單價");
sheet.SetColumnWidth(i - 1, 2 * 160 * 12);
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue(input[1].startTime + "單價");
sheet.SetColumnWidth(i - 1, 2 * 160 * 12);
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue(input[0].startTime + "金額總計");
sheet.SetColumnWidth(i - 1, 2 * 160 * 12);
cell.CellStyle = styleLine12;
cell = row.CreateCell(i++);
cell.SetCellValue(input[1].startTime + "金額總計");
sheet.SetColumnWidth(i - 1, 2 * 160 * 12);
cell.CellStyle = styleLine12;
#endregion
foreach (var r in result)
{
string compareDictKey = r.building_tag + r.floor_tag + r.device_serial_tag + r.device_number;
RowPosition += 1;
int k = 4;
row = sheet.CreateRow(RowPosition);
for (int j = 0; j <= i; j++)
{
cell = row.CreateCell(j);
if (j == 0)
{
cell.SetCellValue(r.building_name);
}
else if (j == 1)
{
cell.SetCellValue(r.floor_tag);
}
else if (j == 2)
{
cell.SetCellValue(r.device_full_name);
}
else if (j == 3)
{
cell.SetCellValue("kWh");
}
else if (j == 4)
{
foreach (var rr in rawDataTitle)
{
var targetRaw = r.rawData.Where(rd => rd.timeStamp == rr).FirstOrDefault();
cell.SetCellValue(targetRaw?.avg_rawdata.ToString() ?? "");
j++;
k++;
cell = row.CreateCell(j);
}
}
if (j == k)
{
cell.SetCellValue(r.total);
}
else if (j == k + 1)
{
cell.SetCellValue(compareDict.ContainsKey(compareDictKey) ? compareDict[compareDictKey][0] : "");
}
else if (j == k + 2)
{
cell.SetCellValue(r.price);
}
else if (j == k + 3)
{
cell.SetCellValue(compareDict.ContainsKey(compareDictKey) ? compareDict[compareDictKey][1] : "");
}
else if (j == k + 4)
{
cell.SetCellValue(r.total_price);
}
else if (j == k + 5)
{
cell.SetCellValue(compareDict.ContainsKey(compareDictKey) ? compareDict[compareDictKey][2] : "");
}
cell.CellStyle = style12;
}
}
}
}
var ms = new NpoiMemoryStream
{
AllowClose = false
};
workbook.Write(ms);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return File(ms, "application/vnd.ms-excel", @$"電表報表{System.DateTime.Now.ToString("yyyyMMddHHmm")}.xlsx");
}
[HttpPost]
[Route("api/ExportElectricEachTotalCompareList")]
public FileResult OpeExportEachTotalCompareExcelElec([FromBody] HydroMeterInput input)
{
bool flag = true;
bool total_flag = false;
string outputFileName = input.Mode == HydroMeterInputSearchMode.All ? "用電月份比較_含分盤_" : "用電月份比較_";
if (input.Mode == HydroMeterInputSearchMode.Custom)
{
//flag = false;
total_flag = true;
input.Mode = HydroMeterInputSearchMode.All;
}
List<HydroMeterOutput> result = new List<HydroMeterOutput>();
result = ElectricListEachTotal(input).Result.Value.Data.ToList();
List<Dictionary<string, byte[]>> docFile = new List<Dictionary<string, byte[]>>();
var workbook = new XSSFWorkbook();
using (FileStream templateStream = new FileStream(".\\template\\ElectricEachTotalCompare_temp.xlsx", FileMode.Open, FileAccess.Read))
{
workbook = new XSSFWorkbook(templateStream);
#region excel設定
IFont font10 = workbook.CreateFont();
font10.FontName = "標楷體";
font10.FontHeightInPoints = 10;
ICellStyle greenCellStyle = workbook.CreateCellStyle();
greenCellStyle.SetFont(font10);
greenCellStyle.Alignment = HorizontalAlignment.Center;
greenCellStyle.VerticalAlignment = VerticalAlignment.Center;
greenCellStyle.FillForegroundColor = IndexedColors.LightGreen.Index;
greenCellStyle.FillPattern = FillPattern.SolidForeground;
greenCellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
greenCellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
greenCellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
greenCellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
ICellStyle style12 = workbook.CreateCellStyle();
style12.SetFont(font10);
style12.Alignment = HorizontalAlignment.Center;
style12.VerticalAlignment = VerticalAlignment.Center;
IFont font12Times = workbook.CreateFont();
font12Times.FontName = "Times New Roman";
font12Times.FontHeightInPoints = 12;
IFont font18 = workbook.CreateFont();
font18.FontName = "標楷體";
font18.FontHeightInPoints = 18;
font18.IsBold = true;
ICellStyle styleTitle18 = workbook.CreateCellStyle();
styleTitle18.SetFont(font18);
styleTitle18.Alignment = HorizontalAlignment.Center;
styleTitle18.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLeft12 = workbook.CreateCellStyle();
styleLeft12.SetFont(font10);
styleLeft12.Alignment = HorizontalAlignment.Left;
styleLeft12.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLine12 = workbook.CreateCellStyle();
styleLine12.SetFont(font10);
styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
styleLine12.VerticalAlignment = VerticalAlignment.Center;
styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
ICellStyle stylein12 = workbook.CreateCellStyle();
stylein12.SetFont(font12Times);
stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
stylein12.VerticalAlignment = VerticalAlignment.Center;
stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.WrapText = true;
#endregion
var sheet = workbook.GetSheetAt(0); // 這裡假設您要使用第一個工作表
// 初始先填表格時間
int rowInit = 0;
int colInit = 0;
IRow row = sheet.GetRow(rowInit++) ?? sheet.CreateRow(rowInit++);
ICell cell = row.GetCell(colInit++) ?? row.CreateCell(colInit++);
DateTime date = DateTime.ParseExact(input.startTime + "-01", "yyyy-MM-dd", null); // 2023-08
date = date.AddYears(-1911);
var start_year = date.ToString("yyy"); // 查詢年
var start_month = date.ToString("MM"); // 查詢月
cell.SetCellValue("明志科技大學" + start_year + "年" + start_month + "月份用電差異比較表");
row = sheet.GetRow(rowInit++) ?? sheet.CreateRow(rowInit++);
colInit = 0;
cell = row.GetCell(colInit++) ?? row.CreateCell(colInit++);
DateTime timeDay = date.AddMonths(1).AddDays(-1); // 用來記錄每個月的最後一天是幾月幾號
string timeRange = start_year + "." + start_month + ".01~" + timeDay.ToString("yyy.MM.dd");
cell.SetCellValue("電錶週期:" + timeRange);
//row = sheet.GetRow(rowInit++) ?? sheet.CreateRow(rowInit++);
//colInit = 3;
//cell = row.GetCell(colInit++) ?? row.CreateCell(colInit++);
//cell.SetCellValue("本月(A)\n" + start_year + "." + start_month);
//cell = row.GetCell(colInit++) ?? row.CreateCell(colInit++);
//DateTime previousMonth = date.AddMonths(-1);
//string lastMonth = previousMonth.ToString("MM");
//cell.SetCellValue("上月(B)\n" + start_year + "." + lastMonth);
//cell = row.GetCell(colInit++) ?? row.CreateCell(colInit++);
//cell.SetCellValue("上月差異(C)\n");
//cell = row.GetCell(colInit++) ?? row.CreateCell(colInit++);
//DateTime previousYear = date.AddYears(-1);
//string lastYear = previousYear.ToString("yyy");
//cell.SetCellValue("去年同期(D)\n" + lastYear + "." + start_month);
//cell = row.GetCell(colInit++) ?? row.CreateCell(colInit++);
//cell.SetCellValue("上年差異(E)\n");
// 設定要填入資料的位置rowIndex 和 columnIndex
int rowIndex = 4; // 假設要從第二列開始填入
int columnIndex = 1; // 假設第一欄是要填入的位置
List<string> need_cal_total = new List<string>
{
"綜合大樓",
"體育舘",
"化工電機",
"創新大樓",
"學人會館",
"綠能中心"
};
List<string> no_cal_sum_device = new List<string>
{
"第一校區總盤",
"電機館分盤",
"第二校區總盤",
"薄膜分盤"
};
List<string> need_green_device = new List<string>
{
"第一校區總盤",
"圖資大樓總盤",
"教學大樓總盤",
"電子館分盤",
"機械館分盤",
"電機館分盤",
"學1-4舍空調總盤",
"學五舍五眷總盤",
"8眷舍分盤",
"企教分盤",
"7眷舍分盤",
"第二校區總盤",
"薄膜一館分盤",
"薄膜二館分盤"
};
int count_index = 1;
string last_build = "";
string last_device = "";
Dictionary<string, Dictionary<string, double>> buildingSumData = new Dictionary<string, Dictionary<string, double>>();
#region
foreach (var item in result)
{
if (!need_cal_total.Contains(item.building_name))
{
continue;
}
if (no_cal_sum_device.Exists(t => t == item.device_full_name))
{
continue;
}
foreach (var dataItem in item.rawData)
{
if (!buildingSumData.ContainsKey(item.building_name))
{
buildingSumData[item.building_name] = new Dictionary<string, double>();
}
if (!buildingSumData[item.building_name].ContainsKey(dataItem.timeStamp))
{
buildingSumData[item.building_name][dataItem.timeStamp] = 0.0;
}
buildingSumData[item.building_name][dataItem.timeStamp] += Math.Round(double.Parse(dataItem.avg_rawdata));
}
}
// 測試
//foreach (var building in buildingSumData)
//{
// Console.WriteLine($"Building: {building.Key}");
// foreach (var timeStampData in building.Value)
// {
// Console.WriteLine($" TimeStamp: {timeStampData.Key}, Total Avg RawData: {timeStampData.Value}");
// }
//}
#endregion
foreach (var r in result)
{
//if (total_flag)
//{
// flag = false;
//}
string buildingName = r.building_name;
string floorTag = r.floor_tag;
string deviceFullName = r.device_full_name;
columnIndex = 0;
// 這兩個盤不納入該棟總計
if (last_device == "電機館分盤" || last_device == "薄膜分盤")
{
flag = false;
}
if ((flag && buildingName == "化工電機" && deviceFullName == "電機館分盤") || (flag && buildingName == "綠能中心" && deviceFullName == "薄膜分盤"))
{
row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(count_index.ToString());
count_index++;
if (total_flag)
{
cell = row.GetCell(columnIndex) ?? row.CreateCell(columnIndex);
cell.SetCellValue(buildingName + floorTag);
}
columnIndex++;
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(last_build + "總計");
cell.CellStyle = greenCellStyle;
foreach (var timeStampData in buildingSumData[last_build])
{
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(timeStampData.Value.ToString());
}
rowIndex++;
last_build = buildingName;
flag = false;
columnIndex = 0;
}
if (flag && buildingName != last_build && need_cal_total.Contains(last_build))
{
row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(count_index.ToString());
count_index++;
if (total_flag)
{
cell = row.GetCell(columnIndex) ?? row.CreateCell(columnIndex);
cell.SetCellValue(buildingName + floorTag);
}
columnIndex++;
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(last_build + "總計");
cell.CellStyle = greenCellStyle;
foreach (var timeStampData in buildingSumData[last_build])
{
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(timeStampData.Value.ToString());
}
rowIndex++;
last_build = buildingName;
// continue;
}
if (total_flag)
{
if (need_green_device.Contains(deviceFullName))
{
columnIndex = 0;
row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(count_index.ToString());
count_index++;
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(buildingName + floorTag);
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(deviceFullName);
cell.CellStyle = greenCellStyle;
foreach (var rawD in r.rawData)
{
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(rawD.avg_rawdata);
}
rowIndex++;
last_build = buildingName;
last_device = deviceFullName;
flag = true;
}
last_build = buildingName;
last_device = deviceFullName;
flag = true;
continue;
}
columnIndex = 0;
row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(count_index.ToString());
count_index++;
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(buildingName + floorTag);
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(deviceFullName);
if (need_green_device.Contains(deviceFullName))
{
cell.CellStyle = greenCellStyle;
}
foreach (var rawD in r.rawData)
{
cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++);
cell.SetCellValue(rawD.avg_rawdata);
}
rowIndex++;
last_build = buildingName;
last_device = deviceFullName;
flag = true;
}
}
var ms = new NpoiMemoryStream
{
AllowClose = false
};
workbook.Write(ms);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return File(ms, "application/vnd.ms", @$"{outputFileName}{System.DateTime.Now.ToString("yyyyMMddHHmm")}.xlsx");
}
[HttpPost]
[Route("api/ElectricListEachTotal")]
public async Task<ActionResult<ApiResult<List<HydroMeterOutput>>>> ElectricListEachTotal([FromBody] HydroMeterInput input)
{
ApiResult<List<HydroMeterOutput>> apiResult = new ApiResult<List<HydroMeterOutput>>(jwt_str);
if (!jwtlife)
{
apiResult.Code = "5000";
return BadRequest(apiResult);
}
string tableType = "day week month year";
if (input.tableType == null || !tableType.Contains(input.tableType))
{
apiResult.Code = "9999";
apiResult.Msg = "表單類別錯誤";
return BadRequest(apiResult);
}
try
{
// 利用今年當月的字串,產生今年上月及去年同月的字串
DateTime date = DateTime.ParseExact(input.startTime, "yyyy-MM", null); // 2023-08
DateTime previousYear = date.AddYears(-1);
DateTime previousMonth = date.AddMonths(-1);
//Console.WriteLine(previousYear.ToString("yyyy-MM")); // 2022-08
//Console.WriteLine(previousMonth.ToString("yyyy-MM")); // 2023-07
var start_year = date.ToString("yyyy"); // 查詢年
var start_month = date.ToString("MM"); // 查詢月
var last_year = previousYear.ToString("yyyy"); // 上個查詢年
var last_month = previousMonth.ToString("MM"); // 上個查詢月
string sqlWhere = "";
string tag_quantity = await backendRepository.GetOneAsync<string>("select system_value from variable where system_type = 'obixConfig' and system_key = 'tag_quantity' and deleted = 0");
//switch (input.Mode)
//{
// case HydroMeterInputSearchMode.All:
// sqlWhere = @$" a.priority <> 0 ";
// break;
// case HydroMeterInputSearchMode.Custom:
// sqlWhere = @$" a.device_number in (SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(system_value, '/', -1), '_', 8) COLLATE utf8mb4_0900_ai_ci as val FROM variable where system_type = 'dashboard_total_elec')";
// break;
// default:
// break;
//}
sqlWhere = @$" a.priority <> 0 ";
var table = "archive_electric_meter_month";
var schema = await backendRepository.GetOneAsync<string>($"select system_value from variable where system_type = 'project_name'");
var isTable = await backendRepository.GetOneAsync<string>($"select table_name from information_schema.tables where table_name = '{table}' and table_schema = '{schema.Split('/')[0]}'");
if (string.IsNullOrEmpty(isTable)) //check for has table or not
{
apiResult.Code = "0000";
apiResult.Data = new List<HydroMeterOutput>() { };
return Ok(apiResult);
}
string header_now = start_year + "-" + start_month;
string header_lastM = start_year + "-" + last_month;
string header_lastY = last_year + "-" + start_month;
var sql = $@"
select e.full_name building_name, a.device_number, '{header_now}' searchMT, ifnull(b.kwh_sum, 0) searchM, '{header_lastM}' lastMT, ifnull(c.kwh_sum, 0) lastM, '{header_lastY}' lastYT, ifnull(d.kwh_sum, 0) lastY
from device a
left join (select device_number, sum(kwh_result) kwh_sum from archive_electric_meter_month where year(start_timestamp) = {start_year} and month(start_timestamp) = {start_month} group by device_number) b on a.device_number COLLATE utf8mb4_0900_ai_ci = b.device_number -- month1
left join (select device_number, sum(kwh_result) kwh_sum from archive_electric_meter_month where year(start_timestamp) = {start_year} and month(start_timestamp) = {last_month} group by device_number) c on a.device_number COLLATE utf8mb4_0900_ai_ci = c.device_number -- month2
left join (select device_number, sum(kwh_result) kwh_sum from archive_electric_meter_month where year(start_timestamp) = {last_year} and month(start_timestamp) = {start_month} group by device_number) d on a.device_number COLLATE utf8mb4_0900_ai_ci = d.device_number -- last Month
join building e on a.device_building_tag = e.building_tag
where {sqlWhere}
order by e.report_priority, a.priority";
Logger.LogInformation("SQL = " + sql + " building=" + input.building_tag + " floor_tag = " + input.floor_tag);
var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataEachTotalOutput>(sql);
List<string> need_green_device = new List<string>
{
"第一校區總盤",
"圖資大樓總盤",
"教學大樓總盤",
"電子館分盤",
"機械館分盤",
"電機館分盤",
"學1-4舍空調總盤",
"學五舍五眷總盤",
"8眷舍分盤",
"企教分盤",
"7眷舍分盤",
"第二校區總盤",
"薄膜一館分盤",
"薄膜二館分盤"
};
List<HydroMeterOutput> ResultData = new List<HydroMeterOutput>();
ResultData = rawData
.GroupBy(x => new { building_tag = x.device_number.Split("_")[1], floor_tag = x.device_number.Split("_")[4], device_master = x.device_number.Split("_")[5], device_serial_tag = x.device_number.Split("_")[7], device_number = x.device_number })
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag, device_master = x.Key.device_master, device_number = x.Key.device_number })
.ToList();
foreach (var l in ResultData)
{
var full_name = await backendRepository.GetOneAsync<string>($"select full_name from device where device_number = '{l.device_number}'");
if (input.Mode == HydroMeterInputSearchMode.Custom && !need_green_device.Contains(full_name))
{
continue;
}
l.rawData = new List<HydroMeterRawDataOutput>();
l.rawData.AddRange(
rawData
.Where(x => x.device_number == l.device_number)
.Select(x => new HydroMeterRawDataOutput
{
timeStamp = x.searchMT, // 或者是您所需的日期格式
device_number = x.device_number,
avg_rawdata = Math.Round(double.Parse(x.searchM)).ToString()
})
);
l.rawData.AddRange(
rawData
.Where(x => x.device_number == l.device_number)
.Select(x => new HydroMeterRawDataOutput
{
timeStamp = x.lastMT, // 或者是您所需的日期格式
device_number = x.device_number,
avg_rawdata = Math.Round(double.Parse(x.lastM)).ToString()
})
);
l.rawData.AddRange(
rawData
.Where(x => x.device_number == l.device_number)
.Select(x => new HydroMeterRawDataOutput
{
timeStamp = "last month different", // 或者是您所需的日期格式
device_number = x.device_number,
avg_rawdata = Math.Round((double.Parse(x.searchM) - double.Parse(x.lastM))).ToString()
})
);
l.rawData.AddRange(
rawData
.Where(x => x.device_number == l.device_number)
.Select(x => new HydroMeterRawDataOutput
{
timeStamp = x.lastYT, // 或者是您所需的日期格式
device_number = x.device_number,
avg_rawdata = Math.Round(double.Parse(x.lastY)).ToString()
})
);
l.rawData.AddRange(
rawData
.Where(x => x.device_number == l.device_number)
.Select(x => new HydroMeterRawDataOutput
{
timeStamp = "last year different", // 或者是您所需的日期格式
device_number = x.device_number,
avg_rawdata = Math.Round(double.Parse(x.searchM) - double.Parse(x.lastY)).ToString()
})
);
l.device_full_name = full_name;
l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
new { building_tag = l.building_tag });
l.total = l.rawData.Where(x => x.avg_rawdata != "NaN").Sum(x => decimal.Parse(x.avg_rawdata ?? "0", System.Globalization.NumberStyles.Float)).ToString();
l.price = input.price.HasValue
? (Math.Round(input.price.Value, 2)).ToString()
: Math.Round((await backendRepository.GetOneAsync<decimal>("select system_value from variable where system_type = 'ElectricPrice' and deleted = 0")), 2).ToString();
l.total_price = Math.Round((Decimal.Parse(l.total) * Decimal.Parse(l.price))).ToString();
}
List<HydroMeterOutput> ResultData_custom = new List<HydroMeterOutput>();
foreach (var l in ResultData)
{
if (l.device_full_name != null)
{
ResultData_custom.Add(l);
}
}
apiResult.Code = "0000";
if (input.Mode == HydroMeterInputSearchMode.All)
{
apiResult.Data = ResultData;
}
else
{
apiResult.Data = ResultData_custom;
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(input);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
public static int GetDayInMonth(string yearMonth)
{
List<string> datesList = new List<string>();
DateTime startOfMonth = DateTime.Parse(yearMonth + "-01");
int daysInMonth = DateTime.DaysInMonth(startOfMonth.Year, startOfMonth.Month);
return daysInMonth;
}
}
}