This is the C# I have downloaded for hiqpdf, but I'm not sure how to amend it so it will work with my html? There are errors coming up om my asp.net c# sheet for textBoxUrl but I'm not sure what namespace I should be using to grab this or whether I need to replace this text?
C# code:
using HiQPdf;
protected void Print_Button_Click(object sender, EventArgs e)
{
// create the HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// select the HTML element to be converted to PDF
htmlToPdfConverter.ConvertedHtmlElementSelector =
textBoxConvertedHtmlElementSelector.Text;
// convert URL to a PDF memory buffer
string url = textBoxUrl.Text;
byte[] pdfBuffer = htmlToPdfConverter.ConvertUrlToMemory(url);
// inform the browser about the binary data format
HttpContext.Current.Response.AddHeader("Content-Type",application/pdf");
// let the browser know how to open the PDF document
HttpContext.Current.Response.AddHeader("Content-Disposition",
String.Format("attachment; filename=ConvertHtmlPart.pdf;
size ={ 0}
",
pdfBuffer.Length.ToString()));
// write the PDF buffer to HTTP response
HttpContext.Current.Response.BinaryWrite(pdfBuffer);
// call End() method of HTTP response
// to stop ASP.NET page processing
HttpContext.Current.Response.End();
}
The textBoxUrl is a TextBox control. You should replace this with your source URL.
e.g for bbc site with "#page" selector.
using HiQPdf;
protected void Print_Button_Click(object sender, EventArgs e)
{
// create the HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// select the HTML element to be converted to PDF
htmlToPdfConverter.ConvertedHtmlElementSelector = "#page"
// convert URL to a PDF memory buffer
string url = "http://www.bbc.com/";
byte[] pdfBuffer = htmlToPdfConverter.ConvertUrlToMemory(url);
// inform the browser about the binary data format
HttpContext.Current.Response.AddHeader("Content-Type",application/pdf");
// let the browser know how to open the PDF document
HttpContext.Current.Response.AddHeader("Content-Disposition",
String.Format("attachment; filename=ConvertHtmlPart.pdf;
size ={ 0}
",
pdfBuffer.Length.ToString()));
// write the PDF buffer to HTTP response
HttpContext.Current.Response.BinaryWrite(pdfBuffer);
// call End() method of HTTP response
// to stop ASP.NET page processing
HttpContext.Current.Response.End();
}
Related
I am generating dynamic .pdf file using asp.net, on some browsers e.g firefox displays the pdf as expected but on I.E & Safari its giving a "Save As" rather than displaying it in the browser. I have used an iFrame for the same. Also to display pdf file is it mandate that the client should have adobe reader or some plugin to display the pdf?
protected void bttnpdf_Click(object sender, EventArgs e)
{
string FilePath = Server.MapPath("sample.pdf");
WebClient User = new WebClient();
Byte[] FileBuffer = User.DownloadData(FilePath);
if (FileBuffer != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", FileBuffer.Length.ToString());
Response.BinaryWrite(FileBuffer);
}
}
Any help would be appreciated.
Thanks in advance
in aspx file :
<div>
<iframe id="myFrame" runat="server" style="width:600px; height:500px;" frameborder="0"></iframe>
</div>
in cs file :
myFrame.src="yourPDFPath"
for example
myFrame.Src = "http://docs.google.com/gview?url=http://path.com/to/your/pdf.pdf&embedded=true";
When I have done this I have also added a content disposition. In the code (can't share it all as it is production code) there is a function that finds a record in the database and returns a FileHandle.
The function returns a FileHandle:
FileStream stream = new FileStream(filePath, FileMode.Open);
var fileHandle = new FileHandle
{
FileStream = stream,
ContentType = "application/pdf",
Filename = fileDownloadName
};
where filePath is the path to the file (e.g. Server.MapPath("sample.pdf") ). In the controller action I have:
var cd = new System.Net.Mime.ContentDisposition
{
// for example foo.bak
FileName = fileHandle.Filename,
// always prompt the user for downloading, set to true if you want
// the browser to try to show the file inline
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(fileHandle.FileStream, fileHandle.ContentType);
Add below line before the line Response.BinaryWrite(FileBuffer);.
Response.AddHeader("Content-Disposition", "inline");
add this header to reponse , so that PDF files will opened in browser itself.
I am using PDFConverter to save a "Receipt page" onto the computer. The way it's set up is I am using a link from Page X to Response.Redirect() to Receipt Page, so it transfers the session data.
Then I am using Session["Cart"] Data to populate the table with the data from the receipt. The problem is, when I use Winnovative PDFConverter to save the page to a file, it doesn't save the table. That's because the table doesn't get populated as Session data isn't sent, (or it creates a new Session, not sure) and as such my saved file does not contain the table, which is the whole point of the Receipt page. How do I get around this? I found a "workaround" online but it doesn't seem to work. It won't even save the file, instead returning an error.
protected void Save_BtnClick(object sender, EventArgs e)
{
PdfConverter converter = new PdfConverter();
string url = HttpContext.Current.Request.Url.AbsoluteUri;
StringWriter sw = new StringWriter();
Server.Execute("Receipt.aspx", sw); //this line triggers an HttpException
string htmlCodeToConvert = sw.GetStringBuilder().ToString();
converter.SavePdfFromUrlToFile(htmlCodeToConvert, #"C:\Users\myname\Downloads\output.pdf"); // <--not even sure what method i should be running here
//converter.SavePdfFromUrlToFile(url,#"C:\Users\myname\Downloads\output.pdf"); <-- this saves it without the table
}
EDIT: One solution I thought of was is it possible to use Winnovative's ability to grab certain elements of the page to pass in the already populated table instead of trying to generate the page automatically using the method? I'm not 100% sure how to work it based on the documentation alone and I do not have access to the sample codes.
I don’t know why the Server.Execute is throwing an exception, but here is an alternative to using that call.
You are using Server.Execute to get the web page to convert to HTML. Instead of that approach have Winnovative make that call. The trick is to allow that page request to access the current user’s session. You specify the URL to call and then supply the user credentials in the cookie collection of the PDFConverter.
See this page and choose the approach based on your authentication technique.
Winnovative Authentication Handling
Edit:
#LordHonydew, We have gone in a big circle in the comments and ended up at the beginning. Let me try this again.
First, in the Server.Execute exception is there an inner exception? There could be more information that helps explain what is going wrong. Even after fixing that issue there are other items that must be fixed.
Second, when using Winnovative to generate a PDF from a web page that is secured you must provide credentials to the PDFConverter so that it can access the page and its resources. There are a couple of ways winnovative can get the HTML: one is by giving the PDFConverter the URL to call and another is to use the Server.Execute to get the HTML directly and then provide the PDFConverter with the HTML, which is how you are doing it. Either way the PDFConverter still needs to talk to the server to get the additional page resources. Things like images and CSS files are not in the HTML, they are referenced by the HTML. The converter will make calls to the server to get these items. Since your application is secured you must provide the converter with credentials to access the server. We will do this by using the same authentication cookie that is used for each page request. There are other ways such as supplying user name and password. That link above explains the various ways.
This code gets the auth cookie from the current request and gives it to the converter:
pdfConverter.HttpRequestCookies.Add(FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
Finally, the converter.SavePdfFromUrlToFile is not the right method to use. That would only save the receipt to the local server’s drive. You need to stream it back to the user.
Try the following. Set a breakpoint in the catch block so you can see if there is an inner exception.
protected void Save_BtnClick(object sender, EventArgs e)
{
// Get the web page HTML as a string
string htmlCodeToConvert = null;
using (StringWriter sw = new StringWriter())
{
try
{
System.Web.HttpContext.Current.Server.Execute("Receipt.aspx", sw);
htmlCodeToConvert = sw.ToString();
}
catch (Exception ex)
{
// set breakpoint below and on an exception see if there is an inner exception.
throw;
}
}
PdfConverter converter = new PdfConverter();
// Supply auth cookie to converter
converter.HttpRequestCookies.Add(System.Web.Security.FormsAuthentication.FormsCookieName,
Request.Cookies[System.Web.Security.FormsAuthentication.FormsCookieName].Value);
// baseurl is used by converter when it gets CSS and image files
string baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority +
Request.ApplicationPath.TrimEnd('/') + "/";
// create the PDF and get as bytes
byte[] pdfBytes = converter.GetPdfBytesFromHtmlString(htmlCodeToConvert, baseUrl);
// Stream bytes to user
Response.Clear();
Response.AppendHeader("Content-Disposition", "attachment;filename=Receipt.pdf");
Response.ContentType = "application/pdf";
Response.OutputStream.Write(pdfBytes, 0, pdfBytes.Length);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
Please check the Convert a HTML Page to PDF in Same Session demo. You can find there a description of the method to use to preserve the session data during conversion and the C# sample code. The code below is copied from there :
protected void convertToPdfButton_Click(object sender, EventArgs e)
{
// Save variables in Session object
Session["firstName"] = firstNameTextBox.Text;
Session["lastName"] = lastNameTextBox.Text;
Session["gender"] = maleRadioButton.Checked ? "Male" : "Female";
Session["haveCar"] = haveCarCheckBox.Checked;
Session["carType"] = carTypeDropDownList.SelectedValue;
Session["comments"] = commentsTextBox.Text;
// Execute the Display_Session_Variables.aspx page and get the HTML string
// rendered by this page
TextWriter outTextWriter = new StringWriter();
Server.Execute("Display_Session_Variables.aspx", outTextWriter);
string htmlStringToConvert = outTextWriter.ToString();
// Create a HTML to PDF converter object with default settings
HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();
// Set license key received after purchase to use the converter in licensed mode
// Leave it not set to use the converter in demo mode
htmlToPdfConverter.LicenseKey = "fvDh8eDx4fHg4P/h8eLg/+Dj/+jo6Og=";
// Use the current page URL as base URL
string baseUrl = HttpContext.Current.Request.Url.AbsoluteUri;
// Convert the page HTML string to a PDF document in a memory buffer
byte[] outPdfBuffer = htmlToPdfConverter.ConvertHtml(htmlStringToConvert, baseUrl);
// Send the PDF as response to browser
// Set response content type
Response.AddHeader("Content-Type", "application/pdf");
// Instruct the browser to open the PDF file as an attachment or inline
Response.AddHeader("Content-Disposition", String.Format("attachment; filename=Convert_Page_in_Same_Session.pdf; size={0}", outPdfBuffer.Length.ToString()));
// Write the PDF document buffer to HTTP response
Response.BinaryWrite(outPdfBuffer);
// End the HTTP response and stop the current page processing
Response.End();
}
Display Session Variables in Converted HTML Page
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
firstNameLabel.Text = Session["firstName"] != null ? (String)Session["firstName"] : String.Empty;
lastNameLabel.Text = Session["lastName"] != null ? (String)Session["lastName"] : String.Empty;
genderLabel.Text = Session["gender"] != null ? (String)Session["gender"] : String.Empty;
bool iHaveCar = Session["haveCar"] != null ? (bool)Session["haveCar"] : false;
haveCarLabel.Text = iHaveCar ? "Yes" : "No";
carTypePanel.Visible = iHaveCar;
carTypeLabel.Text = iHaveCar && Session["carType"] != null ? (String)Session["carType"] : String.Empty;
commentsLabel.Text = Session["comments"] != null ? (String)Session["comments"] : String.Empty;
}
}
I'm using iTextSharp for generating a pdf. I can save the PDF file from the PDF byte[].
byte[] outputPDF = cnt.CreateBreakPDF();
File.WriteAllBytes(pdfOutPutPath, outputPDF);
What is the best way to display the output byte[] to a web page?
I want to show the PDF inside a div in my page. Not the PDF as a full response.
I've seen answers for MVC, but I'm using ASP.NET Web Application.
Is there a better way than using HTTP handlers to do so? I don't want to send all the details for creating PDF as query string.
I tried this in jsFiddle, and it works well in Chrome & FF, need to check on other browsers as well.
Convert the byte[] to Base64 using,
string base64PDF = System.Convert.ToBase64String(outputPDF, 0, outputPDF.Length);
All I had to do is specify the MIME type as data:application/pdf;base64, in the source and give the Base64 version of the PDF.
<object data="data:application/pdf;base64, JVBERi0xLjQKJeLjz9MKMyA..." type="application/pdf" width="160px">
<embed src="data:application/pdf;base64, JVBERi0xLjQKJeLjz9MKMyA..." type="application/pdf" />
</object>
I couldn't be able to hide the top toolbar which appears in FF by appending #toolbar=0&navpanes=0&statusbar=0.
IE8 needs a saved pdf file to be displayed.
Try this
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", outputPDF.Length.ToString());
Response.BinaryWrite(outputPDF);
I have being using Convert.ToBase64String(content) for some projects without any issue, until today with a 18 page file at about 1 MB. The error from Chrome's console is Failed to load resource: net::ERR_INVALID_URL. I guess it's because of the string size?!
I ended up using web api and just return it as FileStreamResult instead of Base64 string.
var stream = new MemoryStream();
await stream.WriteAsync(content, 0, content.Length);
stream.Position = 0;
return new FileStreamResult(stream, "application/pdf");
Update: It's basically the same to display it on a razor page. I just copied my code for retrieving fax content using RingCentral here. And better yet, just use FileContentResult as you already have the byte[].
public async Task<IActionResult> OnGet(string messageId)
{
try
{
using (var rc = new RingCentral.RestClient(setting.ClientId, setting.ClientSecret, setting.Production, "Fax"))
{
await rc.Authorize(setting.UserName, setting.Extension, setting.Password);
var extension = rc.Restapi().Account().Extension();
var outputPDF = await extension.MessageStore(messageId).Content(messageId).Get();
return new FileContentResult(outputPDF, "application/pdf");
}
return Page();
}
catch (Exception ex)
{
_logger.Error(ex.Message);
throw;
}
}
Would something like this work?
<div>
<object data="myPDF.pdf" type="application/pdf" width="200" height="500">
alt : myPDF.pdf
</object>
</div>
You would just need to pass your pdf into the object data source.
My C# web application resides on the C drive.
However the application receives uploaded documents from users and saves them on the D drive.
How do I specify the path to documents on the D drive in the NavigateUrl property of an HyperLink control in the web application on the C drive.
In server-side, you could load the file inside a Stream and response this object as a byte[]
public void Page_Load(object sender, System.EventArgs e)
{
// create a FileStream from a path from local (D:, C:, E:, etc...)
FileStream file = File.OpenRead(#"d:\folder\yourfile.txt");
//Convert the stream to an array of bytes.
byte[] byteArray = file.ToArray();
// Clear all content output from the buffer stream
Response.Clear();
// Add a HTTP header to the output stream that specifies the default filename
// for the browser's download dialog
Response.AddHeader("Content-Disposition", "attachment; filename=foo.txt");
// Add a HTTP header to the output stream that contains the
// content length(File Size). This lets the browser know how much data is being transfered
Response.AddHeader("Content-Length", byteArray.Length.ToString());
// Set the HTTP MIME type of the output stream
Response.ContentType = "application/octet-stream";
// Write the data out to the client.
Response.BinaryWrite(byteArray);
}
If I have a URL to a download, www.website.com/myfile.html
so when that link is clicked it automatically starts a download, which may be myfile.txt for example, how would I get that file into C# for reading..
Is that what Net.WebRequest.Create(url), Net.HttpWebRequest does?
You could achieve this using WebClient:
using (var client = new WebClient())
{
// Download and save the file locally
client.DownloadFile("http://www.website.com/myfile.html", "myfile.html");
}
If you don't want to store the file locally but only read the contents you could try this:
using (var client = new WebClient())
{
string result = client.DownloadString("http://www.website.com/myfile.html");
}
Using C# as an example, here is how one might force the download of a file after clicking a button, link, etc...
public void DownloadFileLink_Click(object sender, EventArgs e)
{
//Get the file data
byte[] fileBytes = Artifacts.Provider.GetArtifact(ArtifactInfo.Id);
//Configure the response header and submit the file data to the response stream.
HttpContext.Current.Response.AddHeader("Content-disposition", "attachment;filename=" + "myDynamicFileName.txt");
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.BinaryWrite(fileBytes);
HttpContext.Current.Response.End();
}
With this in mind, what you need to look for is the Header in the response, the Header will contain an item Content-disposition which will contain the filename of the file being streamed in the response.