使用 Rotativa 从 html 生成 PDF 时出现问题
Problem Generating a PDF from html using Rotativa
我有一个 MVC 页面,它使用 Razor 和 C# 代码的组合来呈现 html 输出。该页面在浏览器中呈现良好。但是,在我的浏览器中,当我使用 Rotativa 生成 PDF 来打印页面时,我得到的似乎是 JSON 输出而不是格式化的 PDF。
我正在使用 Visual Studio 2019 与 .NET 5.0 和 Rotativa 1.7.3。
我知道我可以尝试其他 HTML-to-PDF,但 Rotativa 似乎是最好的开源替代品。
谁能告诉我哪里做错了,这样我就可以将输出呈现为 PDF 格式?
我包含了呈现页面的代码摘录、Rotativa 代码和“PDF”输出。
public async Task<IActionResult> PayrollView(int SelectedCompanyID, string endingWeekString, string endingDateString, int? SelectedEmployeeID)
{
linq query...
PayrollReportView payrollReportView = new PayrollReportView
{
PayrollDetails = await payrollReport.ToListAsync()
};
return View(payrollReportView);
}
public ViewAsPdf PrintPayroll(int SelectedCompanyID, string endingWeekString, string endingDateString, int? SelectedEmployeeID)
{
linq query...
PayrollReportView payrollReportView = new PayrollReportView
{
PayrollDetails = payrollReport.ToList()
};
var report = new ViewAsPdf("PayrollView",payrollReportView);
return report;
}
浏览器中的link(我尝试了 Brave 和 Edge 并确认 Edge 打开 PDF)是:
https://localhost:44383/PayrollReports/PrintPayroll?SelectedCompanyID=13&endingWeekString=2021-11-26
JSON 样的摘录如下:... 代表附加数据,为简洁起见我排除了这些数据。
{
"viewName": "PayrollView",
"masterName": "",
"model": {
"payrollDetails": [
{
"earningsID": 290,
"companyID": 13,
"companyName": "\"D..,\"employees\":null},..\"endingDate\":null},",
"pageSize": null,
"pageWidth": null,
"pageHeight": null,
"pageOrientation": null,
"pageMargins": {},
"wkhtmltopdfPath": "",
"isLowQuality": false,
"copies": null,
"isGrayScale": false,
"fileName": null,
"wkhtmlPath": "",
"cookieName": ".ASPXAUTH",
"formsAuthenticationCookieName": ".ASPXAUTH",
"customHeaders": null,
"cookies": null,
"post": null,
"isJavaScriptDisabled": false,
"minimumFontSize": null,
"proxy": null,
"userName": null,
"password": null,
"customSwitches": null,
"saveOnServerPath": null,
"contentDisposition": 0
}
...
]
}
}
更新:
Edge 和 Brave 都是我的问题。我的视图和 Pdf 控制器事件如下所示。我没有 Javascript 或 AJAX 因为现在我正在做服务器端的所有事情。
public async Task<IActionResult> PayrollView(int SelectedCompanyID, string endingWeekString, string endingDateString, int? SelectedEmployeeID)
{
DateTime dateEndingWeek;
// Convert endingWeek to a date variable
if (endingWeekString == null || endingWeekString.Length == 0)
{
dateEndingWeek = System.DateTime.Today;
}
else
{
dateEndingWeek = DateTime.Parse(endingWeekString);
};
DateTime dateEndingDate;
// Convert endingDateString to a date variable
if (endingDateString == null || endingDateString.Length == 0)
{
dateEndingDate = System.DateTime.Today;
}
else
{
dateEndingDate = DateTime.Parse(endingDateString);
};
// Base query
var payrollReport = from company in _context.Company
join employee in _context.Employees
on company.CompanyID equals employee.CompanyID
join payroll in _context.EmployeeEarnings
on employee.EmployeeID equals payroll.EmployeeID
orderby company.CompanyID, payroll.EmployeeID, payroll.WeekEndingDate
select new PayrollReport
{
EarningsID = payroll.EarningsID,
CompanyID = company.CompanyID,
CompanyName = company.CompanyName,
EmployeeID = employee.EmployeeID,
EmployeeName = employee.EmployeeName,
EmployeeTypeID = employee.EmployeeTypeID,
SSN = employee.SSN.Substring(5, 4),
WeekEndingDate = payroll.WeekEndingDate,
GrossEarnings = payroll.GrossEarnings,
Period401K = payroll.Period401K,
Period401KCatchUp = payroll.Period401KCatchUp,
FederalWithholding = payroll.FederalWithholding,
SSNWithholding = payroll.SSNWithholding,
MedicareWithholding = payroll.MedicareWithholding,
StateWithholding = payroll.StateWithholding,
NetPay = payroll.NetPay,
Tips = payroll.Tips == null ? 0 : payroll.Tips,
Tips_Cash = payroll.Tips_Cash == null ? 0 : payroll.Tips_Cash,
FedExtraWithholding = payroll.FedExtraWithholding,
StateExtraWithholding = payroll.StateExtraWithholding
};
// Check Filters
if (SelectedCompanyID != 0)
payrollReport = payrollReport.Where(x => x.CompanyID == SelectedCompanyID);
if (endingWeekString != null && endingDateString != null)
payrollReport = payrollReport.Where(x => x.WeekEndingDate >= dateEndingWeek && x.WeekEndingDate <= dateEndingDate);
else if (endingWeekString != null)
payrollReport = payrollReport.Where(x => x.WeekEndingDate == dateEndingWeek);
if (SelectedEmployeeID.HasValue)
payrollReport = payrollReport.Where(x => x.EmployeeID == SelectedEmployeeID);
PayrollReportView payrollReportView = new PayrollReportView
{
PayrollDetails = await payrollReport.ToListAsync()
};
if (endingDateString != null)
payrollReportView.endingDate = endingDateString;
// Calculate Sum record if an employee and "end" date are specified
decimal grossTotal = 0;
decimal gross401KTotal = 0;
decimal gross401KCatchUpTotal = 0;
decimal federalTotal = 0;
decimal SSNTotal = 0;
decimal medicareTotal = 0;
decimal stateTotal = 0;
decimal netTotal = 0;
decimal tipsTotal = 0;
decimal tipsCashTotal = 0;
decimal extraFederalTotal = 0;
decimal extraStateTotal = 0;
foreach (var payroll in payrollReportView.PayrollDetails)
{
grossTotal += payroll.GrossEarnings;
gross401KTotal += payroll.Period401K;
gross401KCatchUpTotal += payroll.Period401KCatchUp;
federalTotal += payroll.FederalWithholding;
SSNTotal += payroll.SSNWithholding;
medicareTotal += payroll.MedicareWithholding;
stateTotal += payroll.StateWithholding;
netTotal += payroll.NetPay;
tipsTotal = (decimal)(tipsTotal + payroll.Tips);
tipsCashTotal = (decimal)(tipsCashTotal + payroll.Tips_Cash);
extraFederalTotal = (decimal)(extraFederalTotal + payroll.FedExtraWithholding);
extraStateTotal = (decimal)(extraStateTotal + payroll.StateExtraWithholding);
}
payrollReportView.SumGrossEarnings = grossTotal;
payrollReportView.SumPeriod401K = gross401KTotal;
payrollReportView.SumPeriod401KCatchUp = gross401KCatchUpTotal;
payrollReportView.SumFederalWithholding = federalTotal;
payrollReportView.SumSSNWithholding = SSNTotal;
payrollReportView.SumMedicareWithholding = medicareTotal;
payrollReportView.SumStateWithholding = stateTotal;
payrollReportView.SumNetPay = netTotal;
payrollReportView.SumTips = tipsTotal;
payrollReportView.SumTips_Cash = tipsCashTotal;
payrollReportView.SumFederalWithholding = extraFederalTotal;
payrollReportView.SumStateExtraWithholding = extraStateTotal;
return View(payrollReportView);
}
public ViewAsPdf PrintPayroll(int SelectedCompanyID, string endingWeekString, string endingDateString, int? SelectedEmployeeID)
{
DateTime dateEndingWeek;
// Convert endingWeek to a date variable
if (endingWeekString == null || endingWeekString.Length == 0)
{
dateEndingWeek = System.DateTime.Today;
}
else
{
dateEndingWeek = DateTime.Parse(endingWeekString);
};
DateTime dateEndingDate;
// Convert endingDateString to a date variable
if (endingDateString == null || endingDateString.Length == 0)
{
dateEndingDate = System.DateTime.Today;
}
else
{
dateEndingDate = DateTime.Parse(endingDateString);
};
// Base query
var payrollReport = from company in _context.Company
join employee in _context.Employees
on company.CompanyID equals employee.CompanyID
join payroll in _context.EmployeeEarnings
on employee.EmployeeID equals payroll.EmployeeID
orderby company.CompanyID, payroll.EmployeeID, payroll.WeekEndingDate
select new PayrollReport
{
EarningsID = payroll.EarningsID,
CompanyID = company.CompanyID,
CompanyName = company.CompanyName,
EmployeeID = employee.EmployeeID,
EmployeeName = employee.EmployeeName,
EmployeeTypeID = employee.EmployeeTypeID,
SSN = employee.SSN.Substring(5, 4),
WeekEndingDate = payroll.WeekEndingDate,
GrossEarnings = payroll.GrossEarnings,
Period401K = payroll.Period401K,
Period401KCatchUp = payroll.Period401KCatchUp,
FederalWithholding = payroll.FederalWithholding,
SSNWithholding = payroll.SSNWithholding,
MedicareWithholding = payroll.MedicareWithholding,
StateWithholding = payroll.StateWithholding,
NetPay = payroll.NetPay,
Tips = payroll.Tips == null ? 0 : payroll.Tips,
Tips_Cash = payroll.Tips_Cash == null ? 0 : payroll.Tips_Cash,
FedExtraWithholding = payroll.FedExtraWithholding,
StateExtraWithholding = payroll.StateExtraWithholding
};
// Check Filters
if (SelectedCompanyID != 0)
payrollReport = payrollReport.Where(x => x.CompanyID == SelectedCompanyID);
if (endingWeekString != null && endingDateString != null)
payrollReport = payrollReport.Where(x => x.WeekEndingDate >= dateEndingWeek && x.WeekEndingDate <= dateEndingDate);
else if (endingWeekString != null)
payrollReport = payrollReport.Where(x => x.WeekEndingDate == dateEndingWeek);
if (SelectedEmployeeID.HasValue)
payrollReport = payrollReport.Where(x => x.EmployeeID == SelectedEmployeeID);
PayrollReportView payrollReportView = new PayrollReportView
{
PayrollDetails = payrollReport.ToList()
};
if (endingDateString != null)
payrollReportView.endingDate = endingDateString;
// Calculate Sum record if an employee and "end" date are specified
decimal grossTotal = 0;
decimal gross401KTotal = 0;
decimal gross401KCatchUpTotal = 0;
decimal federalTotal = 0;
decimal SSNTotal = 0;
decimal medicareTotal = 0;
decimal stateTotal = 0;
decimal netTotal = 0;
decimal tipsTotal = 0;
decimal tipsCashTotal = 0;
decimal extraFederalTotal = 0;
decimal extraStateTotal = 0;
foreach (var payroll in payrollReportView.PayrollDetails)
{
grossTotal += payroll.GrossEarnings;
gross401KTotal += payroll.Period401K;
gross401KCatchUpTotal += payroll.Period401KCatchUp;
federalTotal += payroll.FederalWithholding;
SSNTotal += payroll.SSNWithholding;
medicareTotal += payroll.MedicareWithholding;
stateTotal += payroll.StateWithholding;
netTotal += payroll.NetPay;
tipsTotal = (decimal)(tipsTotal + payroll.Tips);
tipsCashTotal = (decimal)(tipsCashTotal + payroll.Tips_Cash);
extraFederalTotal = (decimal)(extraFederalTotal + payroll.FedExtraWithholding);
extraStateTotal = (decimal)(extraStateTotal + payroll.StateExtraWithholding);
}
payrollReportView.SumGrossEarnings = grossTotal;
payrollReportView.SumPeriod401K = gross401KTotal;
payrollReportView.SumPeriod401KCatchUp = gross401KCatchUpTotal;
payrollReportView.SumFederalWithholding = federalTotal;
payrollReportView.SumSSNWithholding = SSNTotal;
payrollReportView.SumMedicareWithholding = medicareTotal;
payrollReportView.SumStateWithholding = stateTotal;
payrollReportView.SumNetPay = netTotal;
payrollReportView.SumTips = tipsTotal;
payrollReportView.SumTips_Cash = tipsCashTotal;
payrollReportView.SumFederalWithholding = extraFederalTotal;
payrollReportView.SumStateExtraWithholding = extraStateTotal;
var report = new ViewAsPdf("PayrollView",payrollReportView);
return report;
//return new RazorPageAsPdf(this);
}
Razor 查看代码:
@model MvcPayroll.Models.PayrollReportView
@{
ViewData["Title"] = "Payroll Register";
}
<link rel="stylesheet" type="text/css" href="site.css" media="screen" />
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
<h1>Payroll Reports</h1>
<p><button>@Html.ActionLink("Download as PDF","PrintPayroll", "PayrollReports",
new
{
SelectedCompanyID = @ViewBag.CompanyID,
endingWeekString = @ViewBag.endingWeekString,
endingDateString = @ViewBag.endingDateString,
SelectedEmployeeID = @ViewBag.SelectedEmployeeId
})</button></p>
<table class="table">
<thead>
<tr>
<th>
Company Name
</th>
<th>
Employee Name
</th>
<th>
SSN
</th>
<th>
Weekending Date
</th>
<th>
Gross Earnings
</th>
<th>
401K
</th>
<th>
401K Catchup
</th>
<th>
Federal Withholding
</th>
<th>
Fed Extra Withholding
</th>
<th>
SSN Withholding
</th>
<th>
Medicare Withholding
</th>
<th>
State Withholding
</th>
<th>
State Extra Withholding
</th>
<th>
Net Pay
</th>
<th>
Tips
</th>
<th>
Tips - Cash
</th>
</tr>
</thead>
<tbody>
@{ decimal subtotalGrossEarnings = 0;
decimal subtotalPeriod401K = 0;
decimal subtotalPeriod401KCatchUp = 0;
decimal subtotalFederalWithholding = 0;
decimal subtotalSSNWithholding = 0;
decimal subtotalMedicareWithholding = 0;
decimal subtotalStateWithholding = 0;
decimal subtotalNetPay = 0;
decimal? subtotalTips = 0;
decimal? subtotalTips_Cash = 0;
decimal? subtotalFedExtraWithholding = 0;
decimal? subtotalStateExtraWithholding = 0;
string oldEmployeeName;
if (Model != null && Model.PayrollDetails.Count() > 0)
oldEmployeeName = Model.PayrollDetails[0].EmployeeName;
else
oldEmployeeName = string.Empty;
@foreach (PayrollReport item in Model.PayrollDetails)
{
// See if employee changed. If it did spit out the Subtotal
@if ((oldEmployeeName != item.EmployeeName) && (Model.endingDate != null))
{
<tr>
<td>
</td>
<td>
Sub Total:
</td>
<td>
</td>
<td>
</td>
<td>
@String.Format("{0:0.00}", subtotalGrossEarnings)
</td>
<td>
@String.Format("{0:0.00}", subtotalPeriod401K)
</td>
<td>
@String.Format("{0:0.00}", subtotalPeriod401KCatchUp)
</td>
<td>
@String.Format("{0:0.00}", subtotalFederalWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalFedExtraWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalSSNWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalMedicareWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalStateWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalStateExtraWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalNetPay)
</td>
<td>
@String.Format("{0:0.00}", subtotalTips)
</td>
<td>
@String.Format("{0:0.00}", subtotalTips_Cash)
</td>
</tr>
oldEmployeeName = item.EmployeeName;
subtotalGrossEarnings = item.GrossEarnings;
subtotalPeriod401K = item.Period401K;
subtotalPeriod401KCatchUp = item.Period401KCatchUp;
subtotalFederalWithholding = item.FederalWithholding;
subtotalSSNWithholding = item.SSNWithholding;
subtotalMedicareWithholding = item.MedicareWithholding;
subtotalStateWithholding = item.StateWithholding;
subtotalNetPay = item.NetPay;
subtotalTips = item.Tips;
subtotalTips_Cash = item.Tips_Cash;
subtotalFedExtraWithholding = item.FedExtraWithholding;
subtotalStateExtraWithholding = item.StateExtraWithholding;
}
else
{
subtotalGrossEarnings = subtotalGrossEarnings + item.GrossEarnings;
subtotalPeriod401K = subtotalPeriod401K + item.Period401K;
subtotalPeriod401KCatchUp = subtotalPeriod401KCatchUp + item.Period401KCatchUp;
subtotalFederalWithholding = subtotalFederalWithholding + item.FederalWithholding;
subtotalSSNWithholding = subtotalSSNWithholding + item.SSNWithholding;
subtotalMedicareWithholding = subtotalMedicareWithholding + item.MedicareWithholding;
subtotalStateWithholding = subtotalStateWithholding + item.StateWithholding;
subtotalNetPay = subtotalNetPay + item.NetPay;
subtotalTips = subtotalTips + item.Tips;
subtotalTips_Cash = subtotalTips_Cash + item.Tips_Cash;
oldEmployeeName = item.EmployeeName;
subtotalFedExtraWithholding = subtotalFedExtraWithholding + item.FedExtraWithholding;
subtotalStateExtraWithholding = subtotalStateExtraWithholding + item.StateExtraWithholding;
}
<tr>
<td>
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
@Html.DisplayFor(modelItem => item.EmployeeName)
</td>
<td>
@Html.DisplayFor(modelItem => item.SSN)
</td>
<td>
@Html.DisplayFor(modelItem => item.WeekEndingDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.GrossEarnings)
</td>
<td>
@Html.DisplayFor(modelItem => item.Period401K)
</td>
<td>
@Html.DisplayFor(modelItem => item.Period401KCatchUp)
</td>
<td>
@Html.DisplayFor(modelItem => item.FederalWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.FedExtraWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.SSNWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.MedicareWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.StateWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.StateExtraWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.NetPay)
</td>
<td>
@Html.DisplayFor(modelItem => item.Tips)
</td>
<td>
@Html.DisplayFor(modelItem => item.Tips_Cash)
</td>
</tr>
}
}
@if (Model.endingDate != null)
{
<tr>
<td>
</td>
<td>
Sub Total:
</td>
<td>
</td>
<td>
</td>
<td>
@String.Format("{0:0.00}", subtotalGrossEarnings)
</td>
<td>
@String.Format("{0:0.00}", subtotalPeriod401K)
</td>
<td>
@String.Format("{0:0.00}", subtotalPeriod401KCatchUp)
</td>
<td>
@String.Format("{0:0.00}", subtotalFederalWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalFedExtraWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalSSNWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalMedicareWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalStateWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalStateExtraWithholding)
</td>
<td>
@String.Format("{0:0.00}", @subtotalNetPay)
</td>
<td>
@String.Format("{0:0.00}", subtotalTips)
</td>
<td>
@String.Format("{0:0.00}", subtotalTips_Cash)
</td>
</tr>
}
</tbody>
<tfoot>
@if (Model.endingDate != null)
{
<tr>
<td>
Totals
</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
@Html.DisplayFor(model => Model.SumGrossEarnings)
</td>
<td>
@Html.DisplayFor(model => Model.SumPeriod401K)
</td>
<td>
@Html.DisplayFor(model => Model.SumPeriod401KCatchUp)
</td>
<td>
@Html.DisplayFor(model => Model.SumFederalWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumFedExtraWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumSSNWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumMedicareWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumStateWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumStateExtraWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumNetPay)
</td>
<td>
@Html.DisplayFor(model => Model.SumTips)
</td>
<td>
@Html.DisplayFor(model => Model.SumTips_Cash)
</td>
</tr>
}
</tfoot>
</table>
旭东,你说的响应头错误是对的。我下载了一个有效的 .net 项目。然后我又做了一些在线搜索,发现我使用的是 .net Core,所以我需要下载 Rotativa 的 .net Core 版本,而不是 .net 4.6 版本。在 link、PDFCore 的一些帮助下,我能够让我的程序生成 PDF。
我有一个 MVC 页面,它使用 Razor 和 C# 代码的组合来呈现 html 输出。该页面在浏览器中呈现良好。但是,在我的浏览器中,当我使用 Rotativa 生成 PDF 来打印页面时,我得到的似乎是 JSON 输出而不是格式化的 PDF。
我正在使用 Visual Studio 2019 与 .NET 5.0 和 Rotativa 1.7.3。
我知道我可以尝试其他 HTML-to-PDF,但 Rotativa 似乎是最好的开源替代品。
谁能告诉我哪里做错了,这样我就可以将输出呈现为 PDF 格式?
我包含了呈现页面的代码摘录、Rotativa 代码和“PDF”输出。
public async Task<IActionResult> PayrollView(int SelectedCompanyID, string endingWeekString, string endingDateString, int? SelectedEmployeeID)
{
linq query...
PayrollReportView payrollReportView = new PayrollReportView
{
PayrollDetails = await payrollReport.ToListAsync()
};
return View(payrollReportView);
}
public ViewAsPdf PrintPayroll(int SelectedCompanyID, string endingWeekString, string endingDateString, int? SelectedEmployeeID)
{
linq query...
PayrollReportView payrollReportView = new PayrollReportView
{
PayrollDetails = payrollReport.ToList()
};
var report = new ViewAsPdf("PayrollView",payrollReportView);
return report;
}
浏览器中的link(我尝试了 Brave 和 Edge 并确认 Edge 打开 PDF)是:
https://localhost:44383/PayrollReports/PrintPayroll?SelectedCompanyID=13&endingWeekString=2021-11-26
JSON 样的摘录如下:... 代表附加数据,为简洁起见我排除了这些数据。
{
"viewName": "PayrollView",
"masterName": "",
"model": {
"payrollDetails": [
{
"earningsID": 290,
"companyID": 13,
"companyName": "\"D..,\"employees\":null},..\"endingDate\":null},",
"pageSize": null,
"pageWidth": null,
"pageHeight": null,
"pageOrientation": null,
"pageMargins": {},
"wkhtmltopdfPath": "",
"isLowQuality": false,
"copies": null,
"isGrayScale": false,
"fileName": null,
"wkhtmlPath": "",
"cookieName": ".ASPXAUTH",
"formsAuthenticationCookieName": ".ASPXAUTH",
"customHeaders": null,
"cookies": null,
"post": null,
"isJavaScriptDisabled": false,
"minimumFontSize": null,
"proxy": null,
"userName": null,
"password": null,
"customSwitches": null,
"saveOnServerPath": null,
"contentDisposition": 0
}
...
]
}
}
更新:
Edge 和 Brave 都是我的问题。我的视图和 Pdf 控制器事件如下所示。我没有 Javascript 或 AJAX 因为现在我正在做服务器端的所有事情。
public async Task<IActionResult> PayrollView(int SelectedCompanyID, string endingWeekString, string endingDateString, int? SelectedEmployeeID)
{
DateTime dateEndingWeek;
// Convert endingWeek to a date variable
if (endingWeekString == null || endingWeekString.Length == 0)
{
dateEndingWeek = System.DateTime.Today;
}
else
{
dateEndingWeek = DateTime.Parse(endingWeekString);
};
DateTime dateEndingDate;
// Convert endingDateString to a date variable
if (endingDateString == null || endingDateString.Length == 0)
{
dateEndingDate = System.DateTime.Today;
}
else
{
dateEndingDate = DateTime.Parse(endingDateString);
};
// Base query
var payrollReport = from company in _context.Company
join employee in _context.Employees
on company.CompanyID equals employee.CompanyID
join payroll in _context.EmployeeEarnings
on employee.EmployeeID equals payroll.EmployeeID
orderby company.CompanyID, payroll.EmployeeID, payroll.WeekEndingDate
select new PayrollReport
{
EarningsID = payroll.EarningsID,
CompanyID = company.CompanyID,
CompanyName = company.CompanyName,
EmployeeID = employee.EmployeeID,
EmployeeName = employee.EmployeeName,
EmployeeTypeID = employee.EmployeeTypeID,
SSN = employee.SSN.Substring(5, 4),
WeekEndingDate = payroll.WeekEndingDate,
GrossEarnings = payroll.GrossEarnings,
Period401K = payroll.Period401K,
Period401KCatchUp = payroll.Period401KCatchUp,
FederalWithholding = payroll.FederalWithholding,
SSNWithholding = payroll.SSNWithholding,
MedicareWithholding = payroll.MedicareWithholding,
StateWithholding = payroll.StateWithholding,
NetPay = payroll.NetPay,
Tips = payroll.Tips == null ? 0 : payroll.Tips,
Tips_Cash = payroll.Tips_Cash == null ? 0 : payroll.Tips_Cash,
FedExtraWithholding = payroll.FedExtraWithholding,
StateExtraWithholding = payroll.StateExtraWithholding
};
// Check Filters
if (SelectedCompanyID != 0)
payrollReport = payrollReport.Where(x => x.CompanyID == SelectedCompanyID);
if (endingWeekString != null && endingDateString != null)
payrollReport = payrollReport.Where(x => x.WeekEndingDate >= dateEndingWeek && x.WeekEndingDate <= dateEndingDate);
else if (endingWeekString != null)
payrollReport = payrollReport.Where(x => x.WeekEndingDate == dateEndingWeek);
if (SelectedEmployeeID.HasValue)
payrollReport = payrollReport.Where(x => x.EmployeeID == SelectedEmployeeID);
PayrollReportView payrollReportView = new PayrollReportView
{
PayrollDetails = await payrollReport.ToListAsync()
};
if (endingDateString != null)
payrollReportView.endingDate = endingDateString;
// Calculate Sum record if an employee and "end" date are specified
decimal grossTotal = 0;
decimal gross401KTotal = 0;
decimal gross401KCatchUpTotal = 0;
decimal federalTotal = 0;
decimal SSNTotal = 0;
decimal medicareTotal = 0;
decimal stateTotal = 0;
decimal netTotal = 0;
decimal tipsTotal = 0;
decimal tipsCashTotal = 0;
decimal extraFederalTotal = 0;
decimal extraStateTotal = 0;
foreach (var payroll in payrollReportView.PayrollDetails)
{
grossTotal += payroll.GrossEarnings;
gross401KTotal += payroll.Period401K;
gross401KCatchUpTotal += payroll.Period401KCatchUp;
federalTotal += payroll.FederalWithholding;
SSNTotal += payroll.SSNWithholding;
medicareTotal += payroll.MedicareWithholding;
stateTotal += payroll.StateWithholding;
netTotal += payroll.NetPay;
tipsTotal = (decimal)(tipsTotal + payroll.Tips);
tipsCashTotal = (decimal)(tipsCashTotal + payroll.Tips_Cash);
extraFederalTotal = (decimal)(extraFederalTotal + payroll.FedExtraWithholding);
extraStateTotal = (decimal)(extraStateTotal + payroll.StateExtraWithholding);
}
payrollReportView.SumGrossEarnings = grossTotal;
payrollReportView.SumPeriod401K = gross401KTotal;
payrollReportView.SumPeriod401KCatchUp = gross401KCatchUpTotal;
payrollReportView.SumFederalWithholding = federalTotal;
payrollReportView.SumSSNWithholding = SSNTotal;
payrollReportView.SumMedicareWithholding = medicareTotal;
payrollReportView.SumStateWithholding = stateTotal;
payrollReportView.SumNetPay = netTotal;
payrollReportView.SumTips = tipsTotal;
payrollReportView.SumTips_Cash = tipsCashTotal;
payrollReportView.SumFederalWithholding = extraFederalTotal;
payrollReportView.SumStateExtraWithholding = extraStateTotal;
return View(payrollReportView);
}
public ViewAsPdf PrintPayroll(int SelectedCompanyID, string endingWeekString, string endingDateString, int? SelectedEmployeeID)
{
DateTime dateEndingWeek;
// Convert endingWeek to a date variable
if (endingWeekString == null || endingWeekString.Length == 0)
{
dateEndingWeek = System.DateTime.Today;
}
else
{
dateEndingWeek = DateTime.Parse(endingWeekString);
};
DateTime dateEndingDate;
// Convert endingDateString to a date variable
if (endingDateString == null || endingDateString.Length == 0)
{
dateEndingDate = System.DateTime.Today;
}
else
{
dateEndingDate = DateTime.Parse(endingDateString);
};
// Base query
var payrollReport = from company in _context.Company
join employee in _context.Employees
on company.CompanyID equals employee.CompanyID
join payroll in _context.EmployeeEarnings
on employee.EmployeeID equals payroll.EmployeeID
orderby company.CompanyID, payroll.EmployeeID, payroll.WeekEndingDate
select new PayrollReport
{
EarningsID = payroll.EarningsID,
CompanyID = company.CompanyID,
CompanyName = company.CompanyName,
EmployeeID = employee.EmployeeID,
EmployeeName = employee.EmployeeName,
EmployeeTypeID = employee.EmployeeTypeID,
SSN = employee.SSN.Substring(5, 4),
WeekEndingDate = payroll.WeekEndingDate,
GrossEarnings = payroll.GrossEarnings,
Period401K = payroll.Period401K,
Period401KCatchUp = payroll.Period401KCatchUp,
FederalWithholding = payroll.FederalWithholding,
SSNWithholding = payroll.SSNWithholding,
MedicareWithholding = payroll.MedicareWithholding,
StateWithholding = payroll.StateWithholding,
NetPay = payroll.NetPay,
Tips = payroll.Tips == null ? 0 : payroll.Tips,
Tips_Cash = payroll.Tips_Cash == null ? 0 : payroll.Tips_Cash,
FedExtraWithholding = payroll.FedExtraWithholding,
StateExtraWithholding = payroll.StateExtraWithholding
};
// Check Filters
if (SelectedCompanyID != 0)
payrollReport = payrollReport.Where(x => x.CompanyID == SelectedCompanyID);
if (endingWeekString != null && endingDateString != null)
payrollReport = payrollReport.Where(x => x.WeekEndingDate >= dateEndingWeek && x.WeekEndingDate <= dateEndingDate);
else if (endingWeekString != null)
payrollReport = payrollReport.Where(x => x.WeekEndingDate == dateEndingWeek);
if (SelectedEmployeeID.HasValue)
payrollReport = payrollReport.Where(x => x.EmployeeID == SelectedEmployeeID);
PayrollReportView payrollReportView = new PayrollReportView
{
PayrollDetails = payrollReport.ToList()
};
if (endingDateString != null)
payrollReportView.endingDate = endingDateString;
// Calculate Sum record if an employee and "end" date are specified
decimal grossTotal = 0;
decimal gross401KTotal = 0;
decimal gross401KCatchUpTotal = 0;
decimal federalTotal = 0;
decimal SSNTotal = 0;
decimal medicareTotal = 0;
decimal stateTotal = 0;
decimal netTotal = 0;
decimal tipsTotal = 0;
decimal tipsCashTotal = 0;
decimal extraFederalTotal = 0;
decimal extraStateTotal = 0;
foreach (var payroll in payrollReportView.PayrollDetails)
{
grossTotal += payroll.GrossEarnings;
gross401KTotal += payroll.Period401K;
gross401KCatchUpTotal += payroll.Period401KCatchUp;
federalTotal += payroll.FederalWithholding;
SSNTotal += payroll.SSNWithholding;
medicareTotal += payroll.MedicareWithholding;
stateTotal += payroll.StateWithholding;
netTotal += payroll.NetPay;
tipsTotal = (decimal)(tipsTotal + payroll.Tips);
tipsCashTotal = (decimal)(tipsCashTotal + payroll.Tips_Cash);
extraFederalTotal = (decimal)(extraFederalTotal + payroll.FedExtraWithholding);
extraStateTotal = (decimal)(extraStateTotal + payroll.StateExtraWithholding);
}
payrollReportView.SumGrossEarnings = grossTotal;
payrollReportView.SumPeriod401K = gross401KTotal;
payrollReportView.SumPeriod401KCatchUp = gross401KCatchUpTotal;
payrollReportView.SumFederalWithholding = federalTotal;
payrollReportView.SumSSNWithholding = SSNTotal;
payrollReportView.SumMedicareWithholding = medicareTotal;
payrollReportView.SumStateWithholding = stateTotal;
payrollReportView.SumNetPay = netTotal;
payrollReportView.SumTips = tipsTotal;
payrollReportView.SumTips_Cash = tipsCashTotal;
payrollReportView.SumFederalWithholding = extraFederalTotal;
payrollReportView.SumStateExtraWithholding = extraStateTotal;
var report = new ViewAsPdf("PayrollView",payrollReportView);
return report;
//return new RazorPageAsPdf(this);
}
Razor 查看代码:
@model MvcPayroll.Models.PayrollReportView
@{
ViewData["Title"] = "Payroll Register";
}
<link rel="stylesheet" type="text/css" href="site.css" media="screen" />
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
<h1>Payroll Reports</h1>
<p><button>@Html.ActionLink("Download as PDF","PrintPayroll", "PayrollReports",
new
{
SelectedCompanyID = @ViewBag.CompanyID,
endingWeekString = @ViewBag.endingWeekString,
endingDateString = @ViewBag.endingDateString,
SelectedEmployeeID = @ViewBag.SelectedEmployeeId
})</button></p>
<table class="table">
<thead>
<tr>
<th>
Company Name
</th>
<th>
Employee Name
</th>
<th>
SSN
</th>
<th>
Weekending Date
</th>
<th>
Gross Earnings
</th>
<th>
401K
</th>
<th>
401K Catchup
</th>
<th>
Federal Withholding
</th>
<th>
Fed Extra Withholding
</th>
<th>
SSN Withholding
</th>
<th>
Medicare Withholding
</th>
<th>
State Withholding
</th>
<th>
State Extra Withholding
</th>
<th>
Net Pay
</th>
<th>
Tips
</th>
<th>
Tips - Cash
</th>
</tr>
</thead>
<tbody>
@{ decimal subtotalGrossEarnings = 0;
decimal subtotalPeriod401K = 0;
decimal subtotalPeriod401KCatchUp = 0;
decimal subtotalFederalWithholding = 0;
decimal subtotalSSNWithholding = 0;
decimal subtotalMedicareWithholding = 0;
decimal subtotalStateWithholding = 0;
decimal subtotalNetPay = 0;
decimal? subtotalTips = 0;
decimal? subtotalTips_Cash = 0;
decimal? subtotalFedExtraWithholding = 0;
decimal? subtotalStateExtraWithholding = 0;
string oldEmployeeName;
if (Model != null && Model.PayrollDetails.Count() > 0)
oldEmployeeName = Model.PayrollDetails[0].EmployeeName;
else
oldEmployeeName = string.Empty;
@foreach (PayrollReport item in Model.PayrollDetails)
{
// See if employee changed. If it did spit out the Subtotal
@if ((oldEmployeeName != item.EmployeeName) && (Model.endingDate != null))
{
<tr>
<td>
</td>
<td>
Sub Total:
</td>
<td>
</td>
<td>
</td>
<td>
@String.Format("{0:0.00}", subtotalGrossEarnings)
</td>
<td>
@String.Format("{0:0.00}", subtotalPeriod401K)
</td>
<td>
@String.Format("{0:0.00}", subtotalPeriod401KCatchUp)
</td>
<td>
@String.Format("{0:0.00}", subtotalFederalWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalFedExtraWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalSSNWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalMedicareWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalStateWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalStateExtraWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalNetPay)
</td>
<td>
@String.Format("{0:0.00}", subtotalTips)
</td>
<td>
@String.Format("{0:0.00}", subtotalTips_Cash)
</td>
</tr>
oldEmployeeName = item.EmployeeName;
subtotalGrossEarnings = item.GrossEarnings;
subtotalPeriod401K = item.Period401K;
subtotalPeriod401KCatchUp = item.Period401KCatchUp;
subtotalFederalWithholding = item.FederalWithholding;
subtotalSSNWithholding = item.SSNWithholding;
subtotalMedicareWithholding = item.MedicareWithholding;
subtotalStateWithholding = item.StateWithholding;
subtotalNetPay = item.NetPay;
subtotalTips = item.Tips;
subtotalTips_Cash = item.Tips_Cash;
subtotalFedExtraWithholding = item.FedExtraWithholding;
subtotalStateExtraWithholding = item.StateExtraWithholding;
}
else
{
subtotalGrossEarnings = subtotalGrossEarnings + item.GrossEarnings;
subtotalPeriod401K = subtotalPeriod401K + item.Period401K;
subtotalPeriod401KCatchUp = subtotalPeriod401KCatchUp + item.Period401KCatchUp;
subtotalFederalWithholding = subtotalFederalWithholding + item.FederalWithholding;
subtotalSSNWithholding = subtotalSSNWithholding + item.SSNWithholding;
subtotalMedicareWithholding = subtotalMedicareWithholding + item.MedicareWithholding;
subtotalStateWithholding = subtotalStateWithholding + item.StateWithholding;
subtotalNetPay = subtotalNetPay + item.NetPay;
subtotalTips = subtotalTips + item.Tips;
subtotalTips_Cash = subtotalTips_Cash + item.Tips_Cash;
oldEmployeeName = item.EmployeeName;
subtotalFedExtraWithholding = subtotalFedExtraWithholding + item.FedExtraWithholding;
subtotalStateExtraWithholding = subtotalStateExtraWithholding + item.StateExtraWithholding;
}
<tr>
<td>
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
@Html.DisplayFor(modelItem => item.EmployeeName)
</td>
<td>
@Html.DisplayFor(modelItem => item.SSN)
</td>
<td>
@Html.DisplayFor(modelItem => item.WeekEndingDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.GrossEarnings)
</td>
<td>
@Html.DisplayFor(modelItem => item.Period401K)
</td>
<td>
@Html.DisplayFor(modelItem => item.Period401KCatchUp)
</td>
<td>
@Html.DisplayFor(modelItem => item.FederalWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.FedExtraWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.SSNWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.MedicareWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.StateWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.StateExtraWithholding)
</td>
<td>
@Html.DisplayFor(modelItem => item.NetPay)
</td>
<td>
@Html.DisplayFor(modelItem => item.Tips)
</td>
<td>
@Html.DisplayFor(modelItem => item.Tips_Cash)
</td>
</tr>
}
}
@if (Model.endingDate != null)
{
<tr>
<td>
</td>
<td>
Sub Total:
</td>
<td>
</td>
<td>
</td>
<td>
@String.Format("{0:0.00}", subtotalGrossEarnings)
</td>
<td>
@String.Format("{0:0.00}", subtotalPeriod401K)
</td>
<td>
@String.Format("{0:0.00}", subtotalPeriod401KCatchUp)
</td>
<td>
@String.Format("{0:0.00}", subtotalFederalWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalFedExtraWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalSSNWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalMedicareWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalStateWithholding)
</td>
<td>
@String.Format("{0:0.00}", subtotalStateExtraWithholding)
</td>
<td>
@String.Format("{0:0.00}", @subtotalNetPay)
</td>
<td>
@String.Format("{0:0.00}", subtotalTips)
</td>
<td>
@String.Format("{0:0.00}", subtotalTips_Cash)
</td>
</tr>
}
</tbody>
<tfoot>
@if (Model.endingDate != null)
{
<tr>
<td>
Totals
</td>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
@Html.DisplayFor(model => Model.SumGrossEarnings)
</td>
<td>
@Html.DisplayFor(model => Model.SumPeriod401K)
</td>
<td>
@Html.DisplayFor(model => Model.SumPeriod401KCatchUp)
</td>
<td>
@Html.DisplayFor(model => Model.SumFederalWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumFedExtraWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumSSNWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumMedicareWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumStateWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumStateExtraWithholding)
</td>
<td>
@Html.DisplayFor(model => Model.SumNetPay)
</td>
<td>
@Html.DisplayFor(model => Model.SumTips)
</td>
<td>
@Html.DisplayFor(model => Model.SumTips_Cash)
</td>
</tr>
}
</tfoot>
</table>
旭东,你说的响应头错误是对的。我下载了一个有效的 .net 项目。然后我又做了一些在线搜索,发现我使用的是 .net Core,所以我需要下载 Rotativa 的 .net Core 版本,而不是 .net 4.6 版本。在 link、PDFCore 的一些帮助下,我能够让我的程序生成 PDF。