所以我在4天后自己弄清楚了。任何需要此功能的人(在 c# 代码中以 PDF 格式呈现 SSRS 报告,从 ASP.NET WEB API 返回 PDF 字节,这是您必须在 webapi 控制器中执行的操作,以从要发送的报告查看器命名空间生成 PDF 字节使用 Redux 到您的 React 应用程序。
WEB API ASP.NET(使用 VS 2019 的 .NET Framework 4.6):
注意:我对第一个选项进行了评论,并且其工作方式与我更喜欢的选项 2 相同。
// return type is Bytes
[HttpGet]
[Route("api/YourReport/{testId}")]
public async Task<IHttpActionResult> GetYourReportAsync(int? testId)
{
if (testId == null)
{
return NotFound();
}
try
{
// 1. Works in this way without '?' on the end of the URL
// URL should be like this: "http://-yourServerName-/reportserver/ReportExecution2005.asmx"
//ReportExecutionService rs = new ReportExecutionService();
//rs.Credentials = CredentialCache.DefaultCredentials;
//rs.Url = "http://-yourServerNamein here-/reportserver/ReportExecution2005.asmx";
//// Render arguments
//byte[] result = null;
//string reportPath = "/-yourReportsFolderName-/-yourReportName-";
//string format = "PDF";
//string historyID = null;
//string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
//// parameters
//ParameterValue[] parameters = new ParameterValue[1];
//parameters[0] = new ParameterValue();
//parameters[0].Name = "yourId";
//parameters[0].Value = testId.ToString();
//string encoding;
//string mimeType;
//string extension;
//Warning[] warnings = null;
//string[] streamIDs = null;
//ExecutionInfo execInfo = new ExecutionInfo();
//ExecutionHeader execHeader = new ExecutionHeader();
//rs.ExecutionHeaderValue = execHeader;
//execInfo = rs.LoadReport(reportPath, historyID);
//rs.SetExecutionParameters(parameters, "en-us");
//string SessionId = rs.ExecutionHeaderValue.ExecutionID;
//try
//{
//// result type is bytes
// result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
//}
//catch (SoapException)
//{
// throw;
//}
//// below, just in case that you want to save it locally in PDF format.
//try
//{
// FileStream stream = File.Create(@"c:\report.pdf", result.Length);
//
// stream.Write(result, 0, result.Length);
// Console.WriteLine("Result written to the file.");
// stream.Close();
//}
//catch (Exception)
//{
// throw;
//}
//return await Task.Run(() => Ok(result));
// 2. Works this way also with '?' on the end of the URL
// URL should be like this: "http://-yourServerName-/reportserver/ReportExecution2005.asmx?"
using (ReportViewer yourReportViewer = new ReportViewer())
{
yourReportViewer.ProcessingMode = ProcessingMode.Remote;
// get the values from your web.config.
yourReportViewer.ServerReport.ReportServerUrl = new Uri(ConfigurationManager.AppSettings["youtReport"]);
yourReportViewer.ServerReport.ReportPath = $"/yourReportsFolder/yourReport";
;
ReportParameter testPlanIdParameter = new ReportParameter();
testPlanIdParameter.Name = "yourId";
testPlanIdParameter.Values.Add(testId.ToString());
yourReportViewer.ServerReport.SetParameters(new ReportParameter[] { testIdParameter });
byte[] yourReportBytes = yourReportViewer.ServerReport.Render("PDF");
return await Task.Run(() => Ok(yourReportBytes));
}
}
catch (SoapException)
{
throw;
}
catch (Exception)
{
throw ;
}
}
REACT/REDUX n强文本注释:您必须将从您的 WEB API 控制器返回的字节流转换为 BLOB 格式,以便在 PDF 格式/类型的新棕色选项卡中呈现它。
一种。按钮动作/行为
<div className="btn-group-vertical" role="group">
<button className="btn btn-sm btn-success ml-2 mb-2" style={{ width: '160px' }} onClick={(e) => openReport(e, testId)}>
<i className="fas fa-print"></i>
Report
</button>
</div>
湾。组件(我省略了 redux 部分(reducers、actions、apiservice...)
openReport(event, item) {
event.preventDefault();
this.props.actions.loadReport(item);
this.setState({ Report: this.props.Report });
const ReportData = this.state.Report;
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
}
const ReportBlob = b64toBlob(ReportData, 'application/pdf');
const ReportBlobUrl = URL.createObjectURL(ReportBlob);
window.open(ReportBlobUrl);
}