i have a Generate PDF fuction, Where i am loading 3 different HTMLS as one pdf.
But i need a page which contains word "Page B" should roate to landscape..because it has some heavy GRID.
public void HTMLToPdfTEST(string[] HTML, string fileName, string folderPath, string physicalApplPath, string requestNumber = "")
{
Document document = new Document();
PdfWriter pdfwriter = PdfWriter.GetInstance(document, new FileStream(physicalApplPath + folderPath + "\\" + fileName + ".pdf", FileMode.Create));
TableHeader tevent = new TableHeader();
tevent.Header = requestNumber;
pdfwriter.PageEvent = tevent;
document.Open();
iTextSharp.text.html.simpleparser.StyleSheet styles = new iTextSharp.text.html.simpleparser.StyleSheet();
iTextSharp.text.html.simpleparser.HTMLWorker hw = new iTextSharp.text.html.simpleparser.HTMLWorker(document);
foreach (string htmlPage in HTML)
{
if (requestNumber.Contains("Page B")){
//do page rotation
hw.Parse(new StringReader(htmlPage));
}
else{
hw.Parse(new StringReader(htmlPage));
}
document.NewPage();
}
document.Close();
}
Got some solution.
//added below line and mentioned it in if condition.
document.SetPageSize(PageSize.A4);
document.Open();
foreach (string htmlPage in HTML)
{
if (requestNumber.Contains("CMC") && HTML[1] != null)
{
//do page rotation
document.SetPageSize(PageSize.A4.Rotate());
hw.Parse(new StringReader(htmlPage));
}
else
{
hw.Parse(new StringReader(htmlPage));
}
document.NewPage();
}
document.Close();
It's working now!!
Related
I'm trying to make an ajax call (I specifically don't want to do it using ActionLink).
I'm having a controller that is like this:
public IActionResult ExportUsers(List<string> listOfEmails)
{
/*some data processing*/
return File(result, "text/csv", "ExportCandidates.csv");
}
On the other side with ajax I do this simple call:
$.ajax({
url: '/Admin/Testcenter/GenerateInvitationPreview',
type: 'post',
data: {
//some input data to send to the controller
},
success: function (response) {
)
}
});
I know there exists something for pdf files where you return a base64 file and with the response in the ajax call you just write something like pdfWindow.document.write(...) and this will open a new window with a pdf file.
Is there a way to extract the response for my CSV file and generate it so the user downloads it ?
USE NPOI Library for Excel Sheet Generation
//Generate Excel Sheet
try
{
Guid gid = Guid.NewGuid();
string ext = ".xls";
string[] Headers = { "Appointments Id", "Date of Appointment", "Doctor Name", "Patient Name", "Visit Type", "Status" };
string fileName = "AppointmentsExcelSheet_" + gid.ToString() + ext;
var serverpath = _env.ContentRootPath;
string rootpath = serverpath + "/wwwroot/ExcelSheets/" + fileName;
FileInfo file = new FileInfo(Path.Combine(rootpath, fileName));
var memorystream = new MemoryStream();
using (var fs = new FileStream(rootpath, FileMode.Create, FileAccess.Write))
{
IWorkbook workbook = new XSSFWorkbook();
ISheet excelSheet = workbook.CreateSheet("Appointments List");
IRow row = excelSheet.CreateRow(0);
var font = workbook.CreateFont();
font.FontHeightInPoints = 11;
font.FontName = "Calibri";
font.Boldweight = (short)FontBoldWeight.Bold;
for (var i = 0; i < Headers.Length; i++)
{
var cell = row.CreateCell(i);
cell.SetCellValue(Headers[i]);
cell.CellStyle = workbook.CreateCellStyle();
cell.CellStyle.SetFont(font);
}
var result = _Appointment.GetAppoinmentsPDf();
int index = 1;
foreach (var app in result.Items)
{
//var PatientDob = Convert.ToDouble(app.PatientDOB);
row = excelSheet.CreateRow(index);
row.CreateCell(0).SetCellValue(app.AppointmentId);
row.CreateCell(1).SetCellValue(app.DateofAppointment+" "+app.TimeofAppointment);
row.CreateCell(2).SetCellValue(app.DoctorFullName);
row.CreateCell(3).SetCellValue(app.SelectedPatientName);
row.CreateCell(4).SetCellValue(app.PurposeofVisit);
if (app.IsActive == false)
{
row.CreateCell(5).SetCellValue("Inactive");
}
else
{
row.CreateCell(5).SetCellValue("Active");
}
index++;
}
workbook.Write(fs);
}
using (var filestream = new FileStream(rootpath, FileMode.Open))
{
filestream.CopyToAsync(memorystream);
}
memorystream.Position = 0;
//send filepath to JQuery function
response.Msg = "/ExcelSheets/" + fileName;
}
catch (Exception Ex)
{
//exception code
}
return Ok(reponse.Msg)
//JavaScript
function AppointmentsExcelSheet() {
//var token = Token;
//var link = path;
debugger
$.ajax({
//'Content-Type': 'application/pdf.',
type: "GET",
url: "/api/Appointments/GetAppointmentsExcelSheet",
beforeSend: function () {
$.blockUI({
message: ('<img src="/images/FadingLines.gif"/>'),
css: {
backgroundColor: 'none',
border: '0',
'z-index': 'auto'
}
});
},
complete: function () {
$.unblockUI();
},
success: function (data) {
debugger
//downloads your Excel sheet
window.location.href = data.msg;
}
});
}
The best way to do what you want to do is to not use AJAX, but use either a link click that opens a new window (since you are passing in parameters) If you could use a
<form target="_blank">
to open a form response. Inside the form can be a field or fields that contains the list of emails (it can be one field, or multiple input fields with the same name). Your action handler can accept that list, parse it, and return a File response, and the natural result of opening the new window from the form post operation is a file that opens up.
I'm try to upload image in database, i'm using drobzone.js
that's my controller code
[HttpGet]
public ActionResult Show(int? id)
{
string mime;
byte[] bytes = LoadImage(id.Value, out mime);
return File(bytes, mime);
}
[HttpPost]
public ActionResult Upload()
{
SuccessModel viewModel = new SuccessModel();
if (Request.Files.Count == 1)
{
var name = Request.Files[0].FileName;
var size = Request.Files[0].ContentLength;
var type = Request.Files[0].ContentType;
viewModel.Success = HandleUpload(Request.Files[0].InputStream, name, size, type);
}
return Json(viewModel);
}
private bool HandleUpload(Stream fileStream, string name, int size, string type)
{
bool handled = false;
try
{
byte[] documentBytes = new byte[fileStream.Length];
fileStream.Read(documentBytes, 0, documentBytes.Length);
Pictures databaseDocument = new Pictures
{
ProfilePicture=documentBytes,
FName=name,
Size=size,
Type=type
};
using(var contxt=new EnglisCenterEntities())
{
contxt.Pictures.Add(databaseDocument);
handled = (contxt.SaveChanges() > 0);
}
}
catch (Exception )
{
// Oops, something went wrong, handle the exception
}
return handled;
}
private byte[] LoadImage(int id, out string type)
{
byte[] fileBytes = null;
string fileType = null;
using(var contxt=new EnglisCenterEntities())
{
var databaseDocument = contxt.Pictures.FirstOrDefault(doc => doc.IdPicture == id);
if (databaseDocument != null)
{
fileBytes = databaseDocument.ProfilePicture;
fileType = databaseDocument.Type;
}
}
type = fileType;
return fileBytes;
}
and this is my script
<script type="text/javascript">
$(document).ready(function () {
$("#preview").fadeOut(15);
$("#refreshButton").click(function () {
var imageToLoad = $("#imageId").val();
if (imageToLoad.length > 0) {
$("#preview").attr("src", "/Document/Show/" + imageToLoad);
$("#preview").fadeIn();
}
});
});
and this is my view
<form action="/Document/Upload" class="dropzone" id="my-awesome-dropzone"></form>
<input type="text" name="imageId" id="imageId" />
<button type="button" id="refreshButton">Update Image</button>
<img src="/" style="display: none" id="preview" />
and it's working with multi images but i want to save single image and prevent the user put more than one image. Is there a way to save a single image and to prevent user put more than an image using dropzone.js?
Javascript is needed to limit maxFiles, see http://www.dropzonejs.com/#configuration-options and http://jsfiddle.net/P2dTF/2/ for example:
Dropzone.autoDiscover = true;
Dropzone.options.my-awesome-dropzone = {
maxFiles: 1
};
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
SuccessModel viewModel = new SuccessModel();
if (file != null)
{
viewModel.Success = HandleUpload(file);
}
return Json(viewModel);
}
Param name of file is important, dropzone binds single upload to param file (and multiple to a param array of files). Don't see why you need a fileStream though, fileStream is needed when you want to return a range of bytes for example with a Request Header (audio) for partial download, HttpPostedFileBase does the job in your case.
private bool HandleUpload(HttpPostedFileBase file)
{
bool handled = false;
try
{
byte[] documentBytes = new byte[file.ContentLength];
Pictures databaseDocument = new Pictures
{
ProfilePicture=documentBytes,
FName=file.FileName,
Size=file.ContentLength,
Type=file.ContentType
};
using(var contxt=new EnglisCenterEntities())
{
contxt.Pictures.Add(databaseDocument);
handled = (contxt.SaveChanges() > 0);
}
}
catch (Exception )
{
// Oops, something went wrong, handle the exception
}
return handled;
}
I have an angular site that I have enabled html5 mode so I can have pretty urls. I need to configure the site for googlebot. What I have done so far is put this in the meta tag:
<meta name="fragment" content="!">
My assumption is by placing that meta tag, I am informing googlebot that it is an ajax site and that it should append _escaped_fragment_ in the url right inbetween domain name and the rest of the of url. For example, if it was trying to crawl http://thehaileselassie.com/Italian_Occupation, it would transform it to http:// thehaileselassie.com/?_escaped_fragment_=Italian_Occupation. But I don't think that is what is happening. I believe it is appending it to the end, like so: http:// thehaileselassie.com/Italian_Occupation?_escaped_fragment_=. I am not quite sure what I am doing wrong.
Extra info
I have this in RouteConfig so all server calls are sent to HomeController:
routes.MapRoute(
name: "Default",
url: "{*url}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And this is the content of the controller:
public ActionResult Index()
{
string fragment = Request.QueryString["_escaped_fragment_"];
if (fragment != null)
{
if (String.IsNullOrWhiteSpace(fragment))
{
string url = "/templates/homeView.html";
return File(Server.MapPath(url), "text/html");
}
else
{
string url = "/templates/" + fragment + ".html";
return File(Server.MapPath(url), "text/html");
}
}
return View();
}
?_escaped_fragment_= is supposed to be appended to end. What I am doing to get the part after the domain is this: Request.Url.LocalPath. This returns /Italian_Occupation. Afterwards I do some logic to create xml on the fly and return it:
string url = "/templates" + Request.Url.LocalPath + ".html";
XmlDocument doc = new XmlDocument();
try
{
doc.Load(Server.MapPath(url));
}
catch
{
return HttpNotFound();
}
var settings = new System.Xml.XmlWriterSettings();
var propInfo = settings.GetType().GetProperty("OutputMethod");
propInfo.SetValue(settings, System.Xml.XmlOutputMethod.Html, null);
var stream = new System.IO.StringWriter();
var writer = System.Xml.XmlWriter.Create(stream, settings);
// XmlElement elem = doc.CreateElement("book", "aaaa", "http://www.com");
//// doc.DocumentElement.AppendChild(elem);
// doc.DocumentElement.(elem, doc.DocumentElement.LastChild);
XmlDocument doc2 = new XmlDocument();
XmlElement element1 = doc2.CreateElement(string.Empty, "html", string.Empty);
doc2.AppendChild(element1);
XmlElement element2 = doc2.CreateElement(string.Empty, "head", string.Empty);
XmlElement element4 = doc2.CreateElement(string.Empty, "title", string.Empty);
XmlText text1 = doc2.CreateTextNode("TheHaileSelassie.Com :: "+doc.GetElementsByTagName("h1")[0].InnerText);
element4.AppendChild(text1);
element2.AppendChild(element4);
doc2.DocumentElement.AppendChild(element2);
XmlElement element3 = doc2.CreateElement(string.Empty, "body", string.Empty);
XmlDocumentFragment xfrag = doc2.CreateDocumentFragment();
xfrag.InnerXml = doc.InnerXml;
element3.AppendChild(xfrag);
doc2.DocumentElement.AppendChild(element3);
//doc2.DocumentElement.AppendChild(xfrag);
doc2.Save(writer);
return Content(System.Net.WebUtility.HtmlDecode(stream.ToString()));
In Microsoft Visual Studio Express I have started a new project using the "Windows Phone HTML5 App" template. If I run the emulator, everything works fine. Next I added the following JavaScript to the index.html page:
<script type="text/javascript">
window.onload = function(){
alert(window.location.href); // --> x-wmapp0:/Html/index.html
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
alert('ON READY STATE CHANGE');
if(xmlhttp.readyState==4){
alert(xmlhttp.responseText);
}
}
//xmlhttp.open("GET","text.txt",true); // I have tried all of these
//xmlhttp.open("GET","Html/text.txt",true);
//xmlhttp.open("GET","/Html/text.txt",true);
xmlhttp.open("GET","x-wmapp0:/Html/text.txt",true);
xmlhttp.send();
}
</script>
Now when I run the app in the emulator I get the first alert with the window location, but do not get any alerts from the readyState or onreadystatechange. The text.txt file is on the same level as the index.html. I have run this code in IE10 and it works just fine. Any ideas on what I am doing wrong?
Update: I have deployed this on an actual Windows 8 phone and got the same result
Cheers
Here is what Microsoft told me from MSDN
XMLHttpRequest only works for retrieving network resources. i.e. You cannot use it to access content from your applications local storage, i.e. XAP or IsolatedStorage.
Here is an example of script + code which I have used in the past to work around this limitation:
HTML Page with JavaScript:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
<script type="text/javascript">
function LoadFile(SourceURL) {
try {
var httpfreq = new XMLHttpRequest();
httpfreq.onreadystatechange = function () {
filecontent.innerText = "httpfreq.onreadystatechange fired, readyState = " + httpfreq.readyState.toString();
if (httpfreq.readyState = 4) {
filecontent.innerText = "Status = " + httpfreq.status.toString();
if (httpfreq.status = 200) {
window.external.notify("Received content" + httpfreq.responseText);
filecontent.innerHTML = httpfreq.responseText;
}
else {
window.external.notify("Error loading page: " + SourceURL);
filecontent.innerText = "Error loading page " + SourceURL;
}
}
};
httpfreq.open("GET", SourceURL);
httpfreq.send(null);
}
catch (e) {
if (e.number = 0x80070005) {
LoadLocalFile(SourceURL, "GetResourceCallback");
}
else {
alert(e.name + " " + e.number.toString());
}
}
}
function LoadLocalFile(SourceURL, callbackfn) {
window.external.notify("GetResource?file=" + SourceURL + ";callback=" + callbackfn);
}
function GetResourceCallback(StringContent) {
filecontent.innerText = StringContent;
}
</script>
</head>
<body>
<p>
test page: notes.html
</p>
<p><input type="button" onclick="LoadFile('text.txt')" value="Load Local" /> </p>
<p><input type="button" onclick="LoadFile('http://www.somedomain.com/text.txt')" value="Load remote" /> </p>
<p>---------------------------</p>
<div id="filecontent"></div>
<p>---------------------------</p>
</body>
</html>
And the required App Host code (c#)
private void webBrowser1_ScriptNotify(object sender, NotifyEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Script Notify : {0}",e.Value);
if (e.Value.Contains("GetResource?file="))
{
Dispatcher.BeginInvoke(() =>
{
String szArgs = e.Value;
string szResource = null;
string szCallbackFn = null;
char[] separators = new char[2] {'?',';'};
string[] parms = szArgs.Split(separators);
for (int i = 1; i < parms.Length; i++ )
{
if (parms[i].Contains("file="))
{
szResource = parms[i].Substring(5);
}
else if (parms[i].Contains("callback="))
{
szCallbackFn = parms[i].Substring(9);
}
}
if (!String.IsNullOrWhiteSpace(szResource) && !String.IsNullOrWhiteSpace(szCallbackFn))
{
// read local resource.
string szFileContent= "Resource not found!";
try
{
if (String.IsNullOrEmpty(webBrowser1.Base))
{
// if Base is not set then assume XAP file content.
szFileContent = ReadXAPResource(szResource);
}
else
{
// else assume IsolatedStorage
szFileContent = ReadISOFile(webBrowser1.Base, szResource);
}
}
catch (Exception)
{}
webBrowser1.InvokeScript(szCallbackFn, szFileContent);
}
});
}
}
private string ReadXAPResource(string szFile)
{
string szContent = "File Not Found";
try
{
// in my project HTML files are in the HelpContent folder...
StringBuilder szPath = new StringBuilder("HelpContent");
if (!szFile.StartsWith("/"))
szPath.Append("/");
szPath.Append(szFile);
StreamResourceInfo sri = Application.GetResourceStream(new Uri(szPath.ToString(), UriKind.Relative));
if (null != sri)
{
StreamReader strm = new StreamReader(sri.Stream);
szContent = strm.ReadToEnd();
}
}
catch (Exception) { }
return szContent;
}
private string ReadISOFile(string szBase, string szFile)
{
string szContent = "File Not Found";
try
{
string fullPath = szBase + szFile;
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream isfsInput = isf.OpenFile(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
if (null != isfsInput)
{
StreamReader strm = new StreamReader(isfsInput);
szContent = strm.ReadToEnd();
}
}
catch (Exception) { }
return szContent;
}
I'm trying to show an image in my HTML file. The image is loaded by Android and stored in SQLite. How can I pass an image (Bitmap) to HTML via AndroidInterface? and what is the correct way to do that?
I would try to save the image to a storage folder then refresh the page within the web component to show the image.
I'm using this approach to show a contextual help for my app. The html pages and images are stored inside a sqlite database.
I'm using WebView:
http://developer.android.com/reference/android/webkit/WebView.html
If you you have a bitmap which saved as a file then you can pass local file path to javascript.
You have to set "setDomStorageEnabled" of WebView as True
<!-- language: lang-java -->
JSONArray list = new JSONArray();
for(...){
JSONObject object = new JSONObject();
try {
object.put("img", "LOCAL_IMAGE_SRC_PATH");
object.put("name", nameString);
list.put(i++, object);
} catch (JSONException e) {}
}
if(mWebView!=null){
mWebView.loadUrl("javascript:addList('" + list + "');");
}
function addContactItem(src, name){
var p = document.createElement("P");
p.innerHTML = name;
var img = document.createElement("IMG");
img.setAttribute("src", src);
img.setAttribute("width", "100");
img.setAttribute("height", "100");
img.setAttribute("alt", "Your image here");
var li = document.createElement("LI");
li.appendChild(img);
li.appendChild(p);
document.getElementById('contact_list').appendChild(li);
};
function addList(list){
var myList = JSON.parse(list);
for(var i=0; i<myList.length; i++){
console.log("img: " + myList[i].img + " name: " + myList[i].name);
addItem(myList[i].img, myList[i].name);
}
};