1
0
Fork 0
master
嘉祥 詹 2024-09-14 01:27:05 +08:00
parent 81e688d70d
commit 3b68b997e5
11 changed files with 368 additions and 4 deletions

View File

@ -13,6 +13,12 @@ using System.Data;
using System;
using AutoMapper;
using Org.BouncyCastle.Asn1.X509;
using NPOI.XSSF.UserModel;
using NPOI.HPSF;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using System.Text;
using System.Web;
namespace QuotationMaker.Controllers
{
@ -21,6 +27,10 @@ namespace QuotationMaker.Controllers
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ISheet sheet;
public FileStream fileStream;
public IWorkbook workbook = null; //新建IWorkbook對象
DbConn dbConn = new DbConn();
SqlConnection conn = new SqlConnection(GlobalClass.appsettings("ConnectionStrings:SQLConnectionString"));
SqlConnection elabConn = new SqlConnection(GlobalClass.appsettings("ConnectionStrings:ElabConnectionString"));
@ -32,6 +42,144 @@ namespace QuotationMaker.Controllers
}
[Route("exportXlsx")]
public ActionResult ExportXlsx(IFormCollection obj) {
normalResult ret = new normalResult();
authToken token = new authToken(this._httpContextAccessor);
if (token.user_isLogin == false)
{
HttpContext.Response.Cookies.Delete("token_key");
ret.ret = "no";
ret.err_code = "99999";
ret.message = "非登入狀態!";
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
}
string quotation_uid = obj["quotation_uid"].ToString();
string quotation_version = obj["quotation_version"].ToString();
quotation objData = conn.QueryFirstOrDefault<quotation>("select * from quotation where quotation_isdel = 'N' and quotation_uid = @quotation_uid and quotation_version = @quotation_version ", new { quotation_uid = quotation_uid, quotation_version = quotation_version });
if (objData == null) {
ret.ret = "no";
ret.err_code = "00009";
ret.message = "無此quotation_uid 與 quotation_version資料!";
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
}
quotationDetail objDetail = new quotationDetail(objData);
string excelName = "";
string ourCompany_name = "";
if (objDetail.dept_uid == "bremen") {
excelName = "bremen_temp.xlsx";
ourCompany_name = "不來梅股份有限公司";
}
if (objDetail.dept_uid == "journeys") {
excelName = "journeys_temp.xlsx";
ourCompany_name = "奇異之旅媒體股份有限公司";
}
string excelFullPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/logo/" + excelName);
FileStream fileStream = new FileStream(excelFullPath, FileMode.Open, FileAccess.ReadWrite);
workbook = new XSSFWorkbook(fileStream);
sheet = workbook.GetSheetAt(0); //獲取第一個工作表
XSSFRow row;
ICell cell = null;
row = (XSSFRow)sheet.GetRow(1);
//估價單名稱與報價日期
row.Cells[0].SetCellValue(row.Cells[0].StringCellValue.Replace("{quotation_date}", objDetail.quotation_date));
row.Cells[3].SetCellValue(row.Cells[3].StringCellValue.Replace("{quotation_name}", objDetail.quotation_name));
//估價單收件人 公司名稱 承辦人
row = (XSSFRow)sheet.GetRow(2);
row.Cells[0].SetCellValue(row.Cells[0].StringCellValue.Replace("{contactPerson_name}", objDetail.contactPerson.contactPerson_name));
row.Cells[2].SetCellValue(row.Cells[2].StringCellValue.Replace("{company_name}", objDetail.company.company_name));
row.Cells[3].SetCellValue(row.Cells[3].StringCellValue.Replace("{user_name}", objDetail.user.user_name));
row = (XSSFRow)sheet.GetRow(3);
row.Cells[0].SetCellValue(row.Cells[0].StringCellValue.Replace("{contactPerson_email}", objDetail.contactPerson.contactPerson_email));
row.Cells[2].SetCellValue(row.Cells[2].StringCellValue.Replace("{company_address}", objDetail.company.company_address));
row.Cells[3].SetCellValue(row.Cells[3].StringCellValue.Replace("{user_email}", objDetail.user.user_email));
row = (XSSFRow)sheet.GetRow(4);
row.Cells[0].SetCellValue(row.Cells[0].StringCellValue.Replace("{company_serialNo}", objDetail.company.company_serialNo));
row.Cells[2].SetCellValue(row.Cells[2].StringCellValue.Replace("{contactPerson_tel}", objDetail.contactPerson.contactPerson_tel));
//估價單契約有效期限
UpperConvert upcov = new UpperConvert();
string startDateStr = upcov.dateToUpper(DateTime.Parse(objDetail.quotation_expStart));
string endDateStr = upcov.dateToUpper(DateTime.Parse(objDetail.quotation_expEnd));
row = (XSSFRow)sheet.GetRow(5);
row.Cells[0].SetCellValue(row.Cells[0].StringCellValue.Replace("{date_range}", startDateStr + " 至 " + endDateStr));
//估價單總價項目
row = (XSSFRow)sheet.GetRow(11);
row.Cells[6].SetCellValue(row.Cells[6].StringCellValue.Replace("{quotation_noTaxTotal}", objDetail.quotation_noTaxTotal.ToString("###,###")));
row = (XSSFRow)sheet.GetRow(12);
string quotation_specTotal = "";
if (objDetail.quotation_specTotal > 0) {
quotation_specTotal = objDetail.quotation_specTotal.ToString("###,###");
}
row.Cells[6].SetCellValue(row.Cells[6].StringCellValue.Replace("{quotation_specTotal}", quotation_specTotal));
row = (XSSFRow)sheet.GetRow(13);
row.Cells[6].SetCellValue(row.Cells[6].StringCellValue.Replace("{quotation_tax}", objDetail.quotation_tax.ToString("###,###")));
row = (XSSFRow)sheet.GetRow(14);
row.Cells[6].SetCellValue(row.Cells[6].StringCellValue.Replace("{quotation_grandTotal}", objDetail.quotation_grandTotal.ToString("###,###")));
//服務協議
string services_aggrement = objDetail.quotation_sa;
services_aggrement = services_aggrement.Replace("##客戶公司##", objDetail.company.company_name + " ");
services_aggrement = services_aggrement.Replace("##我們公司##", ourCompany_name + " ");
row = (XSSFRow)sheet.GetRow(16);
row.Cells[0].SetCellValue(row.Cells[0].StringCellValue.Replace("{quotation_sa}", services_aggrement));
//付款方式與發票
string quotation_grandTotal = ChtNumConverter.ToChtNum((long)objDetail.quotation_grandTotal);
string quotation_grandTotalStr = "本專案費用總計新台幣"+ quotation_grandTotal + "圓整 (即NTD" + objDetail.quotation_grandTotal.ToString("###,###") + "含稅)";
row = (XSSFRow)sheet.GetRow(20);
row.Cells[0].SetCellValue(quotation_grandTotalStr);
MemoryStream ms = new MemoryStream();
workbook.Write(ms);
ms.Flush();
var arrBites = ms.ToArray();
MemoryStream newStream = new MemoryStream(arrBites);
string downloadName = objDetail.quotation_name + " 報價單_" + DateTime.Now.ToString("yyyy-MM-dd");
string agent = Request.Headers["User-Agent"].ToString();
if (agent.Contains("Macintosh"))
{
downloadName = HttpUtility.UrlEncode(downloadName, Encoding.UTF8);
}
return File(newStream, "application/vnd.ms-excel", downloadName + ".xlsx");
return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
}
[Route("saveas")]
public ActionResult SaveAs(IFormCollection obj) {
saveasResult ret = new saveasResult();

View File

@ -221,3 +221,197 @@ public static class GlobalClass
}
}
}
/// <summary>
/// 日期转换为中文大写
/// </summary>
public class UpperConvert
{
public UpperConvert()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
//把数字转换为大写
public string numtoUpper(int num)
{
String str = num.ToString();
string rstr = "";
int n;
for (int i = 0; i < str.Length; i++)
{
n = Convert.ToInt16(str[i].ToString());//char转数字,转换为字符串,再转数字
switch (n)
{
case 0: rstr = rstr + ""; break;
case 1: rstr = rstr + "一"; break;
case 2: rstr = rstr + "二"; break;
case 3: rstr = rstr + "三"; break;
case 4: rstr = rstr + "四"; break;
case 5: rstr = rstr + "五"; break;
case 6: rstr = rstr + "六"; break;
case 7: rstr = rstr + "七"; break;
case 8: rstr = rstr + "八"; break;
default: rstr = rstr + "九"; break;
}
}
return rstr;
}
//月转化为大写
public string monthtoUpper(int month)
{
if (month < 10)
{
return numtoUpper(month);
}
else
if (month == 10) { return "十"; }
else
{
return "十" + numtoUpper(month - 10);
}
}
//日转化为大写
public string daytoUpper(int day)
{
if (day < 20)
{
return monthtoUpper(day);
}
else
{
String str = day.ToString();
if (str[1] == '0')
{
return numtoUpper(Convert.ToInt16(str[0].ToString())) + "十";
}
else
{
return numtoUpper(Convert.ToInt16(str[0].ToString())) + "十"
+ numtoUpper(Convert.ToInt16(str[1].ToString()));
}
}
}
//日期转换为大写
public string dateToUpper(System.DateTime date)
{
int year = date.Year;
int month = date.Month;
int day = date.Day;
return numtoUpper(year) + "年" + monthtoUpper(month) + "月" + daytoUpper(day) + "日";
}
}
public class ChtNumConverter
{
public static string ChtNums = "零壹貳參肆伍陸柒捌玖";
public static Dictionary<string, long> ChtUnits = new Dictionary<string, long>{
{"拾", 10},
{"佰", 100},
{"千", 1000},
{"萬", 10000},
{"億", 100000000},
{"兆", 1000000000000}
};
// 解析中文數字
public static long ParseChtNum(string chtNumString)
{
var isNegative = false;
if (chtNumString.StartsWith("負"))
{
chtNumString = chtNumString.Substring(1);
isNegative = true;
}
long num = 0;
// 處理千百十範圍的四位數
Func<string, long> Parse4Digits = (s) =>
{
long lastDigit = 0;
long subNum = 0;
foreach (var rawChar in s)
{
var c = rawChar.ToString().Replace("", "零");
if (ChtNums.Contains(c))
{
lastDigit = (long)ChtNums.IndexOf(c);
}
else if (ChtUnits.ContainsKey(c))
{
if (c == "十" && lastDigit == 0) lastDigit = 1;
long unit = ChtUnits[c];
subNum += lastDigit * unit;
lastDigit = 0;
}
else
{
throw new ArgumentException($"包含無法解析的中文數字:{c}");
}
}
subNum += lastDigit;
return subNum;
};
// 以兆億萬分割四位值個別解析
foreach (var splitUnit in "兆億萬".ToArray())
{
var pos = chtNumString.IndexOf(splitUnit);
if (pos == -1) continue;
var subNumString = chtNumString.Substring(0, pos);
chtNumString = chtNumString.Substring(pos + 1);
num += Parse4Digits(subNumString) * ChtUnits[splitUnit.ToString()];
}
num += Parse4Digits(chtNumString);
return isNegative ? -num : num;
}
// 轉換為中文數字
public static string ToChtNum(long n)
{
var negtive = n < 0;
if (negtive) n = -n;
if (n >= 10000 * ChtUnits["兆"])
throw new ArgumentException("數字超出可轉換範圍");
var unitChars = "千佰拾".ToArray();
// 處理 0000 ~ 9999 範圍數字
Func<long, string> Conv4Digits = (subNum) =>
{
var sb = new StringBuilder();
foreach (var c in unitChars)
{
if (subNum >= ChtUnits[c.ToString()])
{
var digit = subNum / ChtUnits[c.ToString()];
subNum = subNum % ChtUnits[c.ToString()];
sb.Append($"{ChtNums[(int)digit]}{c}");
}
else sb.Append("零");
}
sb.Append(ChtNums[(int)subNum]);
return sb.ToString();
};
var numString = new StringBuilder();
var forceRun = false;
foreach (var splitUnit in "兆億萬".ToArray())
{
var unit = ChtUnits[splitUnit.ToString()];
if (n < unit)
{
if (forceRun) numString.Append("零");
continue;
}
forceRun = true;
var subNum = n / unit;
n = n % unit;
if (subNum > 0)
numString.Append(Conv4Digits(subNum).TrimEnd('零') + splitUnit);
else numString.Append("零");
}
numString.Append(Conv4Digits(n));
var t = Regex.Replace(numString.ToString(), "[零]+", "零");
if (t.Length > 1) t = t.Trim('零');
t = Regex.Replace(t, "^壹拾", "拾");
return (negtive ? "負" : string.Empty) + t;
}
}

View File

@ -4,6 +4,12 @@ using Dapper;
using static DbTableClass;
public class resultClass
{
public class normalResult
{
public string ret = "no";
public string err_code = "0000";
public string message = "";
}
public class saveasResult
{
public string ret = "no";
@ -172,6 +178,9 @@ public class resultClass
public List<quotationMainItemDetail> quotationMainItemDetails = new List<quotationMainItemDetail>();
public List<payment> payments = new List<payment>();
public List<invoice> invoices = new List<invoice>();
public user user = new user();
public company company = new company();
public contactPerson contactPerson = new contactPerson();
public quotationDetail() { }
@ -192,7 +201,9 @@ public class resultClass
foreach (quotationMainItem qItem in quotationMainItems) {
quotationMainItemDetails.Add(new quotationMainItemDetail(qItem));
}
contactPerson = conn.QueryFirstOrDefault<contactPerson>("select * from contactPerson where contactPerson_uid = @contactPerson_uid ", new { contactPerson_uid = this.contactPerson_uid });
company = conn.QueryFirstOrDefault<company>("select * from company where company_uid = @company_uid", new { company_uid = this.company_uid} );
user = conn.QueryFirstOrDefault<user>("select * from users where user_uid = @user_uid", new { user_uid = this.quotation_create_uid});
payments = conn.Query<payment>("select * from payment where payment_version = @payment_version and quotation_uid = @quotation_uid ", new { payment_version = this.quotation_version, quotation_uid = this.quotation_uid }).ToList();
invoices = conn.Query<invoice>("select * from invoice where invoice_version = @invoice_version and quotation_uid = @quotation_uid ", new { invoice_version = this.quotation_version, quotation_uid = this.quotation_uid }).ToList();
}

View File

@ -250,6 +250,7 @@
<script>
flatpickr.localize(flatpickr.l10ns.zh_tw);
</script>
<script src="https://cdn.jsdelivr.net/gh/mgalante/jquery.redirect@master/jquery.redirect.js"></script>
<!-- BEGIN PAGE LEVEL JS -->
@RenderSection("Script", required: false)
<!-- END PAGE LEVEL JS -->

View File

@ -1910,6 +1910,15 @@ function buttonQuotationClick(obj, view) {
quotationRowPos = quotationTable.fnGetPosition($('#' + uid)[0]);
if (type == "excel") {
var formData = {
quotation_uid: uid,
quotation_version: version
}
$.redirect('/Api/exportXlsx', formData);
}
if (type == "history") {
var formData = {
method: 'get',
@ -2281,9 +2290,10 @@ function loadQuotationTable() {
render: function render(data, type, row, meta) {
var ret = '';
ret += '<button type="button" data-uid="' + row.quotation_uid + '" data-version="' + row.quotation_version + '" data-method="edit" class="btn btn-sm btn-icon btn-secondary" ><i class="fa fa-pencil-alt"></i> <span class="sr-only">Edit</span></button>';
ret += '<button type="button" data-uid="' + row.quotation_uid + '" data-version="' + row.quotation_version + '" data-method="del" class="btn btn-sm btn-icon btn-secondary"><i class="far fa-trash-alt"></i> <span class="sr-only">Remove</span></button>';
ret += '<button type="button" data-uid="' + row.quotation_uid + '" data-version="' + row.quotation_version + '" data-method="history" class="btn btn-sm btn-icon btn-secondary" ><i class="oi oi-list"></i> <span class="sr-only">History</span></button>';
ret += '<button type="button" data-uid="' + row.quotation_uid + '" data-version="' + row.quotation_version + '" data-method="edit" class="btn btn-sm btn-icon btn-secondary" ><i class="fa fa-pencil-alt"></i> <span class="sr-only">Edit</span></button>&nbsp;';
ret += '<button type="button" data-uid="' + row.quotation_uid + '" data-version="' + row.quotation_version + '" data-method="del" class="btn btn-sm btn-icon btn-secondary"><i class="far fa-trash-alt"></i> <span class="sr-only">Remove</span></button>&nbsp;';
ret += '<button type="button" data-uid="' + row.quotation_uid + '" data-version="' + row.quotation_version + '" data-method="history" class="btn btn-sm btn-icon btn-secondary" ><i class="oi oi-list"></i> <span class="sr-only">History</span></button>&nbsp;';
ret += '<button type="button" data-uid="' + row.quotation_uid + '" data-version="' + row.quotation_version + '" data-method="excel" class="btn btn-sm btn-icon btn-secondary" ><i class="far fa-file-excel"></i> <span class="sr-only">History</span></button>';
return ret;
}
}

BIN
wwwroot/logo/bremen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
wwwroot/logo/bremen.xlsx Normal file

Binary file not shown.

Binary file not shown.

BIN
wwwroot/logo/journeys.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
wwwroot/logo/journeys.xlsx Normal file

Binary file not shown.

Binary file not shown.