updates
parent
81e688d70d
commit
3b68b997e5
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 -->
|
||||
|
|
|
|||
|
|
@ -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> ';
|
||||
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="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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue