csharp 在ASP.NET中流式传输和下载RDLC报告
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 在ASP.NET中流式传输和下载RDLC报告相关的知识,希望对你有一定的参考价值。
using System;
using System.IO;
using Microsoft.Reporting.WebForms;
using VelocityFinCrime.Common;
namespace VelocityCMS.Web.Reporting
{
public static class Cmsutility
{
public static byte[] RenderedReportViewer(LocalReport reportViewer, string reportType,out string mimeType)
{
try
{
string encoding;
string fileNameExtension;
var deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>" + reportType + "</OutputFormat>"
//+" <PageWidth>8.5in</PageWidth>" +
//" <PageHeight>11in</PageHeight>" +
//" <MarginTop>0.5in</MarginTop>" +
//" <MarginLeft>1in</MarginLeft>" +
//" <MarginRight>1in</MarginRight>" +
//" <MarginBottom>0.5in</MarginBottom>"
+"</DeviceInfo>";
Warning[] warnings;
string[] streams;
byte[] renderedBytes = reportViewer.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);
return renderedBytes;
}
catch (Exception ex)
{
ex.WriteLog();
mimeType = "application/pdf";
byte[] reBytes = new byte[1];
return reBytes;
}
}
}
}
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using VelocityFinCrime.Entity.TMRS.BusinessEntity;
using VelocityFinCrime.Entity.TMRS.GeneralEntity;
using VelocityFinCrime.Repository.Common.Interface;
using VelocityFinCrime.Repository.TMRS.Interface;
using VelocityFinCrime.TMRS.Manager.Interface;
namespace VelocityFinCrime.TMRS.Manager.Implementation
{
public class TmrsReportManager : ITmrsReportManager
{
private readonly IStrFilingRepository _filing;
private readonly IUserRepository _user;
private readonly IAccountInformationRepository _accountInformation;
private readonly ICustomerAccountRepository _customerAccount;
private readonly ICustomerInformationRepository _customerInformation;
private readonly ICustomerTypeRepository _customerType;
private readonly ICtrFilingRepository _ctrFiling;
private readonly IBranchRepository _branch;
private readonly ISarFilingRepository _sarFilling;
public TmrsReportManager(IStrFilingRepository filling, IStrManager strManager, IUserRepository user, IAccountInformationRepository accountInformation, ICustomerAccountRepository customerAccount, ICustomerInformationRepository customerInformation, ICustomerTypeRepository customerType, ICtrFilingRepository ctrFiling, IBranchRepository branch, ISarFilingRepository sarFilling)
{
_filing = filling;
_user = user;
_accountInformation = accountInformation;
_customerAccount = customerAccount;
_customerInformation = customerInformation;
_customerType = customerType;
_ctrFiling = ctrFiling;
_branch = branch;
_sarFilling = sarFilling;
}
public IQueryable<StrFilingViewModel> GetStatusWiseStr(List<int> branchs, string status)
{
IQueryable<StrFiling> filings;
if(status=="") filings = branchs.Contains(0) ?
_filing.FindAll(s=> !string.IsNullOrEmpty(s.Status)).Include(w => w.StrViolatedRules) :
_filing.All().Where(w => branchs.Contains(w.BranchId)).Include(w => w.StrViolatedRules);
else filings = branchs.Contains(0) ?
_filing.All().Where(w => w.Status == status).Include(w => w.StrViolatedRules) :
_filing.All().Where(w => w.Status == status && branchs.Contains(w.BranchId)).Include(w => w.StrViolatedRules);
var model = StrViewMapping(filings);
return model.OrderBy(o => o.StrId);
}
private IQueryable<StrFilingViewModel> StrViewMapping(IQueryable<StrFiling> filings)
{
var model = from s in filings
join u in _user.All() on s.CreatedUserId equals u.Id
join a in _accountInformation.All() on s.AccountId equals a.Id
join ca in _customerAccount.All() on a.Id equals ca.AccountId
join c in _customerInformation.All() on ca.CustomerId equals c.Id
select new StrFilingViewModel
{
AccountNo = s.AccountNo,
AccountId = s.AccountId,
AccountType = a.AccountType,
CustomerNo = c.CustomerNo,
CustomerType = c.CustomerType,
FullName = (c.FirstName + " " + c.MiddleName + " " + c.LastName).Trim(),
AlertId = s.AlertId,
Status = s.Status == "SEND TO BRANCH" ? "ALERT PENDING IN BRANCH" : s.Status,
IsActive = s.IsActive,
InitialState = s.InitialState,
BranchId = s.BranchId,
BranchName = s.BranchName,
StrId = s.Id,
CreatedUserId = s.CreatedUserId,
CurrentState = s.CurrentState,
CreatedBy = u.FullName,
GenerationDate = s.GenerationDate,
LastComment = s.LastComment,
IsSelected = false,
RuleList = s.RuleList,
RuleCodeList = s.RuleCodeList,
AccountTitle = s.AccountTitle,
Score = s.Score,
KycRiskLevel = s.KycRiskLevel
// RuleList= string.Join(",", s.StrViolatedRules.Select(r=>r.RuleCode))
};
return model;
}
public IQueryable<CustomerBasicInfoViewModel> GetAllCustomerByType(List<int> branchs, string customerType)
{
var cusList = branchs.Contains(0)
? _customerInformation.All()
: _customerInformation.Where(c => branchs.Contains(c.BranchId));
switch (customerType)
{
case "0":
break;
case "ExistingCustomers":
cusList = cusList.Where(a => a.CustomerStatus.ToLower() == "existing");
break;
case "OnboardScreened":
cusList = cusList.Where(a => a.CustomerStatus.ToLower() == "onboard");
break;
default:
cusList = cusList.Where(a => a.CustomerStatus.ToLower() == "onboard");
break;
//default:
// cusList = cusList.Where(a => a.CustomerType.ToUpper() == customerType.ToUpper());
// break;
}
var customerInfo = from c in cusList.OrderBy(a => a.Id)
join s in _customerType.All() on c.CustomerType equals s.Id.ToString()
select new CustomerBasicInfoViewModel
{
Id = c.Id,
OndScrUniqueId = c.OndScrUniqueId,
CustomerNo = c.CustomerNo,
FullName = (!string.IsNullOrEmpty(c.MiddleName) ? c.FirstName + " " + c.MiddleName + " " + c.LastName : c.FirstName + " " + c.LastName).Trim(),
CustomerType = s.Name,
CustomerStatus = c.CustomerStatus,
PresentCountry = c.PresentCountry,
RiskScore = c.RiskScore,
RiskLevel = c.RiskLevel,
KycRiskStatus = c.KycRiskStatus,
AccountStatus = c.AccountStatus,
ScreeningStatus = c.ScreeningStatus,
EntryDate = c.EntryDate
};
var model = customerInfo.OrderByDescending(c => c.Id);
return model;
}
public IQueryable<CtrReviewViewModel> GetStatusWiseCtr(List<int> branchs, string status)
{
IQueryable<CtrFiling> ctr;
if (status == "") ctr = branchs.Contains(0) ?
_ctrFiling.FindAll(s=> !string.IsNullOrEmpty(s.Status)) :
_ctrFiling.FindAll(s => branchs.Contains(s.BranchId));
else ctr = branchs.Contains(0) ?
_ctrFiling.FindAll(s => s.Status == status) :
_ctrFiling.FindAll(s => s.Status == status && branchs.Contains(s.BranchId));
return CtrViewMapping(ctr);
}
private IQueryable<CtrReviewViewModel> CtrViewMapping(IQueryable<CtrFiling> ctr)
{
var model = from s in ctr
join b in _branch.All() on s.BranchId equals b.Id
join u in _user.All() on s.CreatedUserId equals u.Id
join a in _accountInformation.All() on s.AccountId equals a.Id
join ca in _customerAccount.FindAll(a => a.IsActive) on a.Id equals ca.AccountId
join c in _customerInformation.All() on ca.CustomerId equals c.Id
select new CtrReviewViewModel
{
Id = s.Id,
AlertId = s.AlertId,
BranchId = s.BranchId,
AccountId = s.AccountId,
AccountNo = s.AccountNumber,
AccountType = a.AccountType,
CreatedUserId = s.CreatedUserId,
CreatedUserName = u.UserName,
CustomerNo = c.CustomerNo,
CustomerType = c.CustomerType,
FullName = (c.FirstName + " " + c.MiddleName + " " + c.LastName).Trim(),
CurrentState = s.CurrentState,
InitialState = s.InitialState,
IsActive = s.IsActive,
Status = s.Status,
LastComment = s.LastComment,
ModifedUserId = s.ModifedUserId,
EntryDate = s.EntryDate,
EntryTime = s.EntryTime,
IsSelected = false
};
return model.OrderBy(a => a.Id);
}
public IQueryable<SarViewModel> GetStatusWiseSar(List<int> branchs, int currentState, string status)
{
if (status.Contains("_")) { status = status.Replace("_", " "); }
IQueryable<SarFiling> allSar;
if (status == "") allSar = branchs.Contains(0) ?
_sarFilling.Where(s => !string.IsNullOrEmpty(s.Status) && s.CurrentState == currentState) :
_sarFilling.Where(s => branchs.Contains(s.BranchId) && s.CurrentState == currentState);
else allSar = branchs.Contains(0) ?
_sarFilling.Where(s => s.Status == status && s.CurrentState == currentState) :
_sarFilling.Where(s => s.Status == status && branchs.Contains(s.BranchId) && s.CurrentState == currentState);
var model = from s in allSar
join b in _branch.All() on s.BranchId equals b.Id
join c in _user.All() on s.CreatedUserId equals c.Id
select new SarViewModel
{
CustomerId = s.CustomerId,
CustomerNo = s.CustomerNumber,
AlertId = s.AlertId,
Status = s.Status,
IsActive = s.IsActive,
InitialState = s.InitialState,
SuspiciousActivity = s.SuspiciousActivity,
BranchId = b.Id,
BranchCode = b.BranchCode,
BranchName = b.Name,
SarId = s.Id,
CreatedUserId = s.CreatedUserId,
LastComment = s.LastComment,
CurrentState = s.CurrentState,
CreatedBy = c.FullName,
EntryDate = s.EntryDate,
EntryTime = s.EntryTime
};
return model.OrderBy(s => s.SarId);
}
}
}
using Microsoft.Reporting.WebForms;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using PagedList;
using VelocityCMS.Web.Reporting;
using VelocityFinCrime.Common;
using VelocityFinCrime.Entity;
using VelocityFinCrime.Entity.Common.GeneralEntity;
using VelocityFinCrime.Entity.Config;
using VelocityFinCrime.Entity.TMRS.BusinessEntity;
using VelocityFinCrime.Manager;
using VelocityFinCrime.Manager.Interface;
using VelocityFinCrime.Screening.Manager.Interface;
using VelocityFinCrime.TMRS.Manager.Interface;
namespace VelocityFinCrime.Web.Controllers
{
public class ReportController : BaseController
{
private readonly IBranchManager _branch;
private readonly IBaseManager _baseManager;
private readonly IGlobalConfigManager _config;
private readonly IStrManager _str;
private readonly ITmrsReportManager _reportManager;
private readonly IRelatedPartyManager _relatedParty;
IEnumerable<DropdownItemList> ReportTypes = new List<DropdownItemList>
{
new DropdownItemList {Id = StrStatusEnum.SEND_TO_BRANCH.EnumToString(), Name = "Alert pending in Branch"},
new DropdownItemList {Id = StrStatusEnum.ALERT_CLEARED.EnumToString(), Name = "Alert cleared"},
new DropdownItemList {Id = StrStatusEnum.REPORTED_TO_FIU.EnumToString(), Name = "BFIU Reported"},
new DropdownItemList {Id = StrStatusEnum.CASE_CREATED.EnumToString(), Name = "Pending in CMS"}
};
IEnumerable<DropdownItemList> ReportNames = new List<DropdownItemList>
{
new DropdownItemList {Id = "STR", Name= "STR"},
new DropdownItemList {Id = "SAR", Name= "SAR"},
new DropdownItemList {Id = "CTR", Name= "CTR"},
new DropdownItemList {Id = "RISK",Name = "KYC,CDD & RISK"}
};
private IEnumerable<DropdownItemList> _kycReportTypes = new List<DropdownItemList>
{
new DropdownItemList {Id = KycStatusForReportEnum.OnboardScreened.EnumToString(), Name = "Onboard Screened"},
new DropdownItemList {Id = KycStatusForReportEnum.OnboardRelatedPartyScreened.EnumToString(), Name = "Onboard Related Party Screened"},
new DropdownItemList {Id = KycStatusForReportEnum.OnboardKyc.EnumToString(), Name = "Onboard KYC"},
new DropdownItemList {Id = KycStatusForReportEnum.ExistingCustomers.EnumToString(), Name = "Existing Customers"}
};
public ReportController(IBranchManager branch, IBaseManager baseManager, IGlobalConfigManager config, IStrManager str, ITmrsReportManager reportManager, IRelatedPartyManager relatedParty)
{
_branch = branch;
_baseManager = baseManager;
_config = config;
_str = str;
_reportManager = reportManager;
_relatedParty = relatedParty;
}
//public ActionResult SearchReport(string reportName, string reportType, string reportFormat, int branchId, string startDate = "", string endDate = "")
//{
// DateTime? sDate = !string.IsNullOrEmpty(startDate) ? DateTime.ParseExact(startDate, "MMM dd, yyyy", null).Date : DateTime.MinValue;
// DateTime? eDate = !string.IsNullOrEmpty(endDate) ? DateTime.ParseExact(endDate, "MMM dd, yyyy", null).Date : DateTime.Now.Date;
// dynamic result = _reportManager.GetStatusWiseCtr(new List<int> { branchId }, reportType).Where(c => c.EntryDate >= sDate && c.EntryDate <= eDate).ToList();
// return PartialView("");
//}
public ActionResult Index()
{
return PartialView();
}
public ActionResult Graph()
{
return PartialView();
}
public ActionResult General()
{
var lstBranch = _branch.GetPermittedBranches(Settings.PermittedBranchs);
ViewData["BranchList"] = lstBranch;
var model = new ReportingViewModel { ReportTypes = ReportTypes, ReportNames = ReportNames };
return PartialView(model);
}
public ActionResult GetReportType(string reportName)
{
if (reportName == "STR" || reportName == "CTR" || reportName == "SAR")
{
var reportType = new List<SelectListItem>
{
new SelectListItem {Value = StrStatusEnum.SEND_TO_BRANCH.EnumToString(), Text = "Alert pending in Branch"},
new SelectListItem {Value = StrStatusEnum.ALERT_CLEARED.EnumToString(), Text = "Alert cleared"},
new SelectListItem {Value = StrStatusEnum.REPORTED_TO_FIU.EnumToString(),Text = "BFIU Reported"},
new SelectListItem {Value = StrStatusEnum.CASE_CREATED.EnumToString(), Text = "Pending in CMS"}
};
return Json(reportType, JsonRequestBehavior.AllowGet);
}
else
{
var reportType = new List<SelectListItem>
{
new SelectListItem {Value = KycStatusForReportEnum.ExistingCustomers.EnumToString(), Text = "Existing Customers"},
new SelectListItem {Value = KycStatusForReportEnum.OnboardScreened.EnumToString(), Text = "Onboard Screened Customers"},
new SelectListItem {Value = KycStatusForReportEnum.OnboardRelatedPartyScreened.EnumToString(), Text = "Onboard Related Party Screened Customers"},
new SelectListItem {Value = KycStatusForReportEnum.OnboardKyc.EnumToString(), Text = "Onboard KYC"}
};
return Json(reportType, JsonRequestBehavior.AllowGet);
}
}
public ActionResult HtmlReport(int? page, string reportName, string reportType, string reportFormat, int branchId, string startDate = "", string endDate = "", int pageSize = 30)
{
DateTime sDate = !string.IsNullOrEmpty(startDate) ? DateTime.ParseExact(startDate, "MMM dd, yyyy", null).Date : DateTime.MinValue;
DateTime eDate = !string.IsNullOrEmpty(endDate) ? DateTime.ParseExact(endDate, "MMM dd, yyyy", null).Date : DateTime.Now.Date;
ViewBag.reportName = reportName;
ViewBag.reportType = reportType == "" ? "all" : reportType;
ViewBag.reportFormat = reportFormat;
ViewBag.branchId = branchId;
ViewBag.startDate = startDate;
ViewBag.endDate = endDate;
ViewBag.pageSize = pageSize;
dynamic model;
switch (reportName)
{
case "CTR":
model = GetReportBody(reportName, reportType=="all"? "": reportType, branchId, sDate, eDate);
List<CtrReviewViewModel> ctrViewModelList = new List<CtrReviewViewModel>();
foreach (var x in model) { ctrViewModelList.Add((CtrReviewViewModel)x); }
var dataCtr = ctrViewModelList.ToPagedList(page ?? 1, pageSize);
return PartialView("CTR", dataCtr);
case "STR":
model = GetReportBody(reportName, reportType == "all" ? "" : reportType, branchId, sDate, eDate);
List<StrFilingViewModel> strViewModelList = new List<StrFilingViewModel>();
foreach (var x in model) { strViewModelList.Add((StrFilingViewModel)x); }
var dataStr = strViewModelList.ToPagedList(page ?? 1, pageSize);
return PartialView("STR", dataStr);
case "SAR":
model = GetReportBody(reportName, reportType == "all" ? "" : reportType, branchId, sDate, eDate);
List<SarViewModel> sarViewModelList = new List<SarViewModel>();
foreach (var x in model) { sarViewModelList.Add((SarViewModel)x); }
var dataSar = sarViewModelList.ToPagedList(page ?? 1, pageSize);
return PartialView("SAR", dataSar);
case "RISK":
model = GetReportBody(reportName, reportType == "all" ? "" : reportType, branchId, sDate, eDate);
List<CustomerBasicInfoViewModel> riskViewModelList = new List<CustomerBasicInfoViewModel>();
foreach (var x in model) { riskViewModelList.Add((CustomerBasicInfoViewModel)x); }
return PartialView("Risk", riskViewModelList.ToPagedList(page ?? 1, pageSize));
default:
return PartialView("CTR");
}
}
public ActionResult ListReportViewer(string reportName, string reportType, string reportFormat, int branchId, string startDate = "", string endDate = "")
{
DateTime sDate;
DateTime eDate;
return RdlcListReport(reportName, reportType, reportFormat, branchId, startDate, endDate, out sDate, out eDate);
}
//public ActionResult DetailReportViewer(string reportName)
//{
//}
private string GetReportParh(string reportName, string reportType)
{
switch (reportName)
{
case "STR":
return Path.Combine(Server.MapPath("~/Reporting/rdlc/STR/"), "RptStrBulk.rdlc");
case "CTR":
return Path.Combine(Server.MapPath("~/Reporting/rdlc/CTR/"), "RptCtrBulk.rdlc");
case "SAR":
return Path.Combine(Server.MapPath("~/Reporting/rdlc/SAR/"), "RptSarBulk.rdlc");
case "RISK":
return Path.Combine(Server.MapPath("~/Reporting/rdlc/KYC/"), "ExistingCustomers.rdlc");
default:
return null;
}
}
private ActionResult RdlcListReport(string reportName, string reportType, string reportFormat, int branchId, string startDate, string endDate, out DateTime sDate, out DateTime eDate)
{
var header = GetReportHeader(reportName, reportType, branchId, startDate, endDate, out sDate, out eDate);
var reportViewer = new LocalReport
{
EnableExternalImages = true,
ReportPath = GetReportParh(reportName, reportType)
};
var rptHead = new ReportDataSource("ReportHeader", header.ToDataTable());
reportViewer.DataSources.Add(rptHead);
var reportData = GetReportBody(reportName, reportType, branchId, sDate, eDate);
var rptDs = new ReportDataSource("ReportBody", reportData);
reportViewer.DataSources.Add(rptDs);
string mimeType;
var renderedBytes = Cmsutility.RenderedReportViewer(reportViewer, reportFormat, out mimeType);
return File(renderedBytes, mimeType);
}
private dynamic GetReportBody(string reportName, string reportType, int branchId, DateTime sDate, DateTime eDate)
{
dynamic result;
int currentState = _baseManager.CurrentState(Settings.RoleId, reportName);
switch (reportName)
{
case "STR":
result = _reportManager.GetStatusWiseStr(new List<int> { branchId }, reportType).Where(c => c.GenerationDate >= sDate && c.GenerationDate <= eDate);
return result;
case "CTR":
result = _reportManager.GetStatusWiseCtr(new List<int> { branchId }, reportType).Where(c => c.EntryDate >= sDate && c.EntryDate <= eDate).ToList();
return result;
case "SAR":
result = _reportManager.GetStatusWiseSar(new List<int> { branchId }, currentState, reportType).Where(c => c.EntryDate >= sDate && c.EntryDate <= eDate);
return result;
case "RISK":
var customers = _reportManager.GetAllCustomerByType(new List<int> { branchId }, reportType)
.Where(c => c.EntryDate >= sDate && c.EntryDate <= eDate);
var model = new List<CustomerBasicInfoViewModel>();
switch (reportType)
{
case "OnboardScreened":
foreach (var item in customers)
{
var status = _relatedParty.PartyScreeningStatus(item.Id);
if ((item.RiskScore == 100) &&
(status == ScreeningStatus.PENDING.ToString() || status == ScreeningStatus.NOTSCREENED.ToString()))
model.Add(item);
}
break;
case "OnboardRelatedPartyScreened":
foreach (var item in customers)
{
var status = _relatedParty.PartyScreeningStatus(item.Id);
if ((item.RiskScore == 100) &&
(status == ScreeningStatus.RELEASED.ToString()))
model.Add(item);
}
break;
case "OnboardKyc":
foreach (var item in customers)
{
if (item.RiskScore < 100)
model.Add(item);
}
break;
default:
model = new List<CustomerBasicInfoViewModel>(customers);
break;
}
return model;
default:
return null;
}
}
private ReportHeader GetReportHeader(string reportName, string reportType, int branchId, string startDate, string endDate, out DateTime sDate, out DateTime eDate)
{
sDate = !string.IsNullOrEmpty(startDate) ? DateTime.ParseExact(startDate, "MMM dd, yyyy", null).Date : DateTime.MinValue;
eDate = !string.IsNullOrEmpty(endDate) ? DateTime.ParseExact(endDate, "MMM dd, yyyy", null).Date : DateTime.Now;
var bName = branchId == 0 ? "All Branch" : "Branch: " + _baseManager.GetBranch(branchId).Name;
var hasSignatory = _config.GetValue("Report", "Signatory") ?? "No";
var hasSignatorySign = _config.GetValue("ReportSign", "SignatorySign") ?? "Yes";
var rptName = "";
switch (reportType.ToUpper())
{
case "ON DEMAND":
rptName = "On Demand Screening Result";
break;
case "REMITTANCE":
rptName = "Remittance Screening Result";
break;
case "CBS":
rptName = "CBS Screening Result";
break;
case "SCHEDULE":
rptName = "Existing Customer Screening Result";
break;
case "SWIFT":
rptName = "Swift Screening Result";
break;
case "SEND TO BRANCH":
rptName = "Alert pending in Branch";
break;
case "ALERT CLEARED":
rptName = "Cleared Alerts";
break;
case "REPORTED TO FIU":
rptName = "BFIU Reported";
break;
case "CASE CREATED":
rptName = "Pending in CMS";
break;
case "ONBOARDSCREENED":
rptName = "Onboard Screened Customers";
break;
case "ONBOARDRELATEDPARTYSCREENED":
rptName = "Onboard Related Party Screened Customers";
break;
case "ONBOARDKYC":
rptName = "Onboard KYC";
break;
case "EXISTINGCUSTOMERS":
rptName = "Existing Customers";
break;
default:
rptName = reportType + " Screening Result";
break;
}
OrganizationInformation company = _baseManager.GetCompanyDetails();
var head = new ReportHeader
{
Name = company.Name,
BranchName = bName,
ReportName = rptName,
FromDate = !string.IsNullOrEmpty(startDate) ? sDate : (DateTime?)null,
ToDate = !string.IsNullOrEmpty(endDate) ? eDate : (DateTime?)null,
Logo = new Uri(Server.MapPath("~/Images/Logo/logo.png")).AbsoluteUri,
MimeType = company.MimeType,
HasSignatory = hasSignatory.ToLower() == "yes",
HasSignatorySign = hasSignatorySign.ToLower() == "no"
};
return head;
}
}
}
以上是关于csharp 在ASP.NET中流式传输和下载RDLC报告的主要内容,如果未能解决你的问题,请参考以下文章