使用React/Redux从ASP.NET WEB API获取要以PDF格式呈现的字节数组
我使用从SSRS报告链接返回字节的.NET在WEBAPI的控制器上执行此操作:使用React/Redux从ASP.NET WEB API获取要以PDF格式呈现的字节数组,pdf,asp.net-web-api,react-redux,Pdf,Asp.net Web Api,React Redux,我使用从SSRS报告链接返回字节的.NET在WEBAPI的控制器上执行此操作: public IHttpActionResult GetReport(int? Id) { if (Id == null) { return NotFound(); } var reportServer = ConfigurationManager.AppSettings["Report"];
public IHttpActionResult GetReport(int? Id)
{
if (Id == null)
{
return NotFound();
}
var reportServer = ConfigurationManager.AppSettings["Report"];
var reportPath = $"{reportServer}/myReport&Id={Id}&rs:Format=PDF";
WebClient Client = new WebClient();
Client.UseDefaultCredentials = true;
byte[] reportBytes = Client.DownloadData(reportPath);
var reportBase64 = Convert.ToBase64String(reportBytes);
return Ok(reportBase64);
}
当我尝试使用这个react/redux代码从这个返回生成PDF时(我使用的是axios)
…它打开了一个带有PDF模板的新浏览器选项卡,但显示PDF错误为:“无法加载PDF文档”
任何地方都没有人能帮我解决这个问题(
注意:“axios”调用它返回的字节数组与WEBAPI返回的字节数组相同,“myReportData”变量也一样。因此,我在4天后自己就知道了。有人需要这个功能吗(在c#代码中以PDF格式呈现SSRS报告,从ASP.NET WEB API返回PDF字节,以下是您必须在webapi控制器中执行的操作,以从报告查看器命名空间生成PDF字节,并使用Redux发送到React应用程序 WEB API ASP.NET(.NET Framework 4.6使用VS 2019): 注意:第一个选项与我更喜欢的选项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 ;
}
}
//返回类型为字节
[HttpGet]
[路由(“api/YourReport/{testId}”)]
公共异步任务GetYourReportAsync(int?testId)
{
if(testId==null)
{
返回NotFound();
}
尝试
{
//1.以这种方式工作,URL末尾不带“?”
//URL应如下所示:http://-yourServerName-/reportserver/ReportExecution2005.asmx"
//ReportExecutionService rs=新的ReportExecutionService();
//rs.Credentials=CredentialCache.DefaultCredentials;
//rs.Url=”http://-yourServerNamein 此处-/reportserver/ReportExecution2005.asmx”;
////渲染参数
//字节[]结果=空;
//string reportPath=“/-yourReportsFolderName-/-yourReportName-”;
//string format=“PDF”;
//字符串historyID=null;
//字符串devInfo=@“False”;
////参数
//ParameterValue[]参数=新参数值[1];
//参数[0]=新参数值();
//参数[0]。Name=“yourId”;
//参数[0]。值=testId.ToString();
//字符串编码;
//字符串模拟类型;
//字符串扩展;
//警告[]警告=null;
//字符串[]streamIDs=null;
//ExecutionInfo ExecutionInfo=新的ExecutionInfo();
//ExecutionHeader ExecutionHeader=新的ExecutionHeader();
//rs.ExecutionHeaderValue=ExecutionHeader;
//execInfo=rs.LoadReport(reportPath,historyID);
//rs.SetExecutionParameters(参数“en-us”);
//字符串SessionId=rs.ExecutionHeaderValue.ExecutionID;
//试一试
//{
////结果类型为字节
//结果=rs.Render(格式、devInfo、输出扩展、输出编码、输出mimeType、输出警告、输出streamid);
//}
//捕获(SoapException)
//{
//投掷;
//}
////下面,以防您希望以PDF格式在本地保存它。
//试一试
//{
//FileStream stream=File.Create(@“c:\report.pdf”,result.Length);
//
//stream.Write(result,0,result.Length);
//WriteLine(“结果写入文件”);
//stream.Close();
//}
//捕获(例外)
//{
//投掷;
//}
//返回等待任务。运行(()=>Ok(结果));
//2.以这种方式与URL末尾的“?”一起使用
//URL应如下所示:http://-yourServerName-/reportserver/ReportExecution2005.asmx?"
使用(ReportViewer yourReportViewer=new ReportViewer())
{
yourReportViewer.ProcessingMode=ProcessingMode.Remote;
//从web.config获取值。
yourReportViewer.ServerReport.ReportServerUrl=新Uri(ConfigurationManager.AppSettings[“youtReport”]);
yourReportViewer.ServerReport.ReportPath=$“/yourReportsFolder/yourReport”;
;
ReportParameter testPlanIdParameter=新的ReportParameter();
testPlanIdParameter.Name=“yourId”;
testPlanIdParameter.Values.Add(testId.ToString());
yourReportViewer.ServerReport.SetParameters(新的ReportParameter[]{TestedParameter});
byte[]yourReportBytes=yourReportViewer.ServerReport.Render(“PDF”);
返回等待任务。运行(()=>Ok(yourReportBytes));
}
}
捕获(SoapException)
{
投
}
捕获(例外)
{
投
}
}
REACT/REDUX nstrong text注意:您必须将从WEB API控制器返回的字节流转换为BLOB格式,以PDF格式/类型在新的brownser选项卡中呈现
a、 按钮的动作/行为
<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>
openReport(e,testId)}>
汇报
b、 组件(我省略了redux部分(减速机、操作、apiservice…)
openReport(事件、项目){
event.preventDefault();
this.props.actions.loadReport(项目);
this.setState({Report:this.props.Report});
const ReportData=this.state.Report;
const b64toBlob=(b64Data,contentType='',sliceSize=512)=>{
常量ByTechCharacters=atob(B64数据);
常量字节数组=[];
for(让offset=0;offset <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>
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);
}