I am generating a report in an MVC project. The user has the option of getting the report in either .pdf format or .xls
I am using Aspose.Cells for the Excel file generation. The ActionResult method below is called.
[HttpGet]
public ActionResult GenerateReport(string format, string filterDate = "")
{
//Processing occurs here to get the appropriate info from Db.
var fileFormat = format.ToUpper() == "PDF" ? Format.Pdf : Format.Csv;
var contentType = fileFormat == Format.Pdf ? "application/pdf" : "application/vnd.ms-excel";
var makePdf = fileFormat == Format.Pdf;
var fileContents = register.GetReport(makePdf, filterDate);
return File(fileContents, contentType, "Report");
}
register.GetReport() merely determines if GetExcelVersion() or GetPdfVersion() is called.
private void GetExcelVersion(MemoryStream stream, string name, string dateRequested = "")
{
var license = new Aspose.Cells.License();
license.SetLicense("Aspose.Total.lic");
var workbook = new Workbook();
var worksheet = workbook.Worksheets[0];
var cells = worksheet.Cells;
//writes out the appropriate information to the excel spreadsheet here
workbook.Save(stream, new XlsSaveOptions(Aspose.Cells.SaveFormat.Excel97To2003));
}
This works a charm in Firefox and IE10 but when testing on IE8 I receive the following alert from Excel:-
The File you are trying to open 'XXXXX', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now? Yes/No
Any ideas on what I am doing wrong?
Cheers!
As Saqib Razzaq mentioned in the comments above. Turn off compatibility mode as mentioned here
Related
I am trying to upload a file to a .net core 2 rest API while in the same POST request also upload metadata (which will be stored in database). By metadata I mean a few info about the file (uploader, date/time of upload and just a few more) as Json format.
I have searched and tried different ways found on Stackoverflow but none worked. I am right now at this point.
The API Controller:
[HttpPost]
[Consumes("multipart/form-data")]
public async Task<ActionResult> upload(IFormFile file, MyMetadata metadata)
{
// my logic
}
The client:
using (var fileStream = File.OpenRead(filePath))
{
using (var multiPartFormDataContent = new MultipartFormDataContent())
{
multiPartFormDataContent.Add
(
new StreamContent(fileStream)
{
Headers =
{
ContentLength = fileStream.Length,
ContentType = new MediaTypeHeaderValue("application/octet-stream")
}
}
, "file"
, Path.GetFileName(filePath)
);
var link = /mycontroller/upload;
var resultTask = client.PostAsync(link, multiPartFormDataContent);
var result = await resultTask;
I have tried adding the model to multPartFormDataContent but without success.
So what I am asking for, is a complete solution Controller and Client in same answer that will work.
As each user runs through my application I hold their data and dump it into a report as follows, which at the end is created into a pdf document and is later automatically downloaded on the users side(client-side). I now want to attach this document to an email and have it forwarded to them. This is where I have troubles with the attachment.
Code as follows:
ReportDocument rd = new ReportDocument();
rd.Load(Path.Combine(Server.MapPath("~/Reports/PP_RentalAgreement.rpt")));
rd.SetParameterValue("rent_agree_no", _1);
rd.SetParameterValue("r_initial", _2);
rd.SetParameterValue("r_f_name", _3);
rd.SetParameterValue("r_l_name", _4);
rd.SetParameterValue("r_id_no", _5);
rd.SetParameterValue("r_lic_no", _6);
rd.SetParameterValue("r_tel", _7);
rd.SetParameterValue("r_cell", _8);
rd.SetParameterValue("r_fax", _9);
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
Stream st = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
st.Seek(0, SeekOrigin.Begin);
if (ModelState.IsValid)
{
var m_message = new MailMessage();
m_message.To.Add(new MailAddress("JoeSoap#TextMail.com"));
m_message.Subject = "Pink Panther - Invoice";
m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf"));
using (var smtp = new SmtpClient())
{
await smtp.SendMailAsync(m_message);
return RedirectToAction("Index");
}
}
I am getting an error on this line : m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf")); saying The specified content type is invalid.
Someone suggested to me that I should specify a path however I am not actually saving this file anywhere
How am I able to allow the file to be attached and send it to the recipient?
The System.Net.Mail.Attachment class constructor with 3 overloads consist of these parameters:
public Attachment(System.IO.Stream contentStream, string name, string mediaType)
Hence, you're assigning name and content type in reversed order, which causing invalid content type problem at this code:
m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf"));
The correct way is putting the file name as second argument like example below:
m_message.Attachments.Add(new Attachment(st, "Invoice.pdf", "application/pdf"));
Or using MediaTypeNames for content type setting:
m_message.Attachments.Add(new Attachment(st, "Invoice.pdf", MediaTypeNames.Application.Pdf));
I have the following code:
var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
htmlToPdf.PdfToolPath = "~/files/";
htmlToPdf.GeneratePdf(template);
Which throws the following error:
Uri is not supported when saving pdf in server folder with nreco pdf generator.
You will need to set a regular path to your file system like e.g. "C:\temp\myfolder\". Or use a . instead of ~ and backslashes:
htmlToPdf.PdfToolPath = ".\\files\\";
If NReco is able to deliver you an byte-array or a stream you should prefer this instead of a file and return it directly.
UPDATE:
After takeing a look into the documentation of NReco all you need to do is following:
var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
htmlToPdf.PdfToolPath = "<CORRECT_PATH_FOR_TOOL>";
var output = htmlToPdf.GeneratePdf(template);
System.IO.File.WriteAllBytes("<OUTPUT_PATH>", output);
This should create your pdf in the OUTPUT_PATH.
#OlaFW thanx for your effort.
I got my answer.
var pdfBytes = htmlToPdf.GeneratePdf(template);
string filePath = "/files/Myfile.pdf";
string Url = System.Web.Hosting.HostingEnvironment.MapPath(filePath);
System.IO.File.WriteAllBytes(Url, pdfBytes);
I am using Rotativa to generate a pdf from a view I have created. Locally this works fine, the pdf is stored on my local computer and the email functiont then attaches and sends the file. But when I release it on our server, it basically breaks at this part:
var binary = pdf.BuildPdf(this.ControllerContext);
The website takes ages to load and then finally just says
Sorry, an error occurred while processing your request.
What i did to test this was to redirect to the actual view which will be generated in a pdf until this error was shown. I thought the issue was that the website does not have any write rights but could create directories in the required folder up until the above part mentioned.
What can I do to solve this?
Here is my full section of code for this part:
string Switches = string.Format("--print-media-type --header-html {0} --footer-html {1}", Url.Action("Header", "Home", new { area = "" }, "http"), Url.Action("Footer", "Home", new { area = "" }, "http"));
var fileName = ReportName+objScor.Name+"_"+objScor.Surname + DateTime.Now.ToString("dd MMM yyyy HHmmss") + ".pdf";
var filePath =(#"C:\\PDFReport\\" + fileName);
if (!System.IO.File.Exists(#"C:\\PDFReport\\"))
{
Directory.CreateDirectory(#"C:\\PDFReport\\");
}
var pdf = new Rotativa.ViewAsPdf("Report", report)
{
FileName = fileName,
CustomSwitches = Switches
};
var binary = pdf.BuildPdf(this.ControllerContext);
Thanks in advance.
I want to download a file from an URL, the file name is updated frequently
For E.g.: filename_Date.zip where date changes.
Below is the Query I used
WebClient webClient = new WebClient();
webClient.DownloadFile("http://nppes.viva-it.com/NPPES_Deactivated_NPI_Report_081214.zip", #"C:\Users\gnanasem\Documents\NPIMatcher\NPI.zip");
Landing Page of the URL: http://nppes.viva-it.com/NPI_Files.html
Here you can see multiple files and I want to download the first one.
One way of doing this is to:
Get the HTML of the webpage
Find the URLs on the webpage using RegEx
Find the first URL containing the relevant text, in your case "Deactivated"
Download the file
I got it working like this:
using (var webClient = new WebClient())
{
var websiteHtml = webClient.DownloadString("http://nppes.viva-it.com/NPI_Files.html");
var urlPattern = "href\\s*=\\s*(?:[\"'](?<1>[^\"']*)[\"']|(?<1>\\S+))";
Match match = Regex.Match(websiteHtml, urlPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled, TimeSpan.FromSeconds(1));
var urlToDownload = string.Empty;
while (match.Success)
{
var urlFound = match.Groups[1].Value;
if (urlFound.ToLower().Contains("deactivated"))
{
urlToDownload = urlFound;
break;
}
match = match.NextMatch();
}
webClient.DownloadFile(urlToDownload, #"C:\Users\gnanasem\Documents\NPIMatcher\NPI.zip");
}