Javascript can manipulate the document the browser is displaying, so the following:
<script>
document.write("<table><tr><td>Hola</td><td>Adios</td></tr></table>");
</script>
Will make the browser display a table just like if it was the original HTML document:
<table>
<tr>
<td>Hola</td>
<td>Adios</td>
</tr>
</table>
Is there a way I can save/serve this document content?
Currently we have some nicely generated reports using Ext-js, what I would like to do is to have the "text/html" version of it ( I mean, something that doesn't require javascript )
So at the end of the page I would add a button : "Save as blaba" and the document should display the text/plain version.
The only way I could think right now is, to write the content into a javascript variable like:
var content = document.toString(); // or something magic like that.
// post it to the server
Then post that value to the server, and have the server present that value.
<%=request.getParameter("content-text")%>
But looks very tricky.
Is there an alternative?
EDIT
Ok, I almost got it. Now I just need the new window to pop up so the option "would you like to save it shows"
This is what I've got so far
<script>
document.write("<div id='content'><table><tr><td>Hola</td><td>Adios</td></tr></table></div>");
function saveAs(){
var sMarkup = document.getElementById('content').innerHTML;
var oNewDoc = document.open('application/vnd.ms-excel');
oNewDoc.write( sMarkup + "<hr>" );
oNewDoc.close();
}
</script>
<input type="button" value="Save as" onClick="saveAs()"/>
The line:
var oNewDoc = document.open('application/vnd.ms-excel');
Should specify the new content type, but it is being ignored.
Here's the upgraded version to open the table contents in .xls format.
<head>
<script>
document.write("<table id='targetTable'><tr><td>Hola</td><td>Adios</td></tr><tr><td>eins</td><td>zwei</td></table>");
function saveAsXLS()
{
var xlObj = new ActiveXObject("Excel.Application");
var xlBook = xlObj.Workbooks.Add();
var xlSheet = xlBook.Worksheets(1);
for (var y=0;y<targetTable.rows.length;y++) // targetTable=id of the table
{
for (var x=0;x<targetTable.rows(y).cells.length;x++)
{
xlSheet.Cells(y+1,x+1)=targetTable.rows(y).cells(x).innerText;
}
}
xlObj.Visible=true;
document.write("The table contents are opened in a new Excel sheet.");//Print on webpage
}
</script>
</head>
<body>
<input type="button" value="Open table in Excel!" onclick="saveAsXLS()"/>
</body>
This code is tested in IE6 and is using ActiveXObject control.
- The table I've used here is of order 2x2 and the individual contents are mapped respectively into the excel sheet.
- Unlike the .doc version, this does not save the file in client's system. It opens the application with the table content and the client has to save it.
Hope this helps in answering ur question. Lemme know if u face any issues.
Peace.
Unless its being saved client side with File -> Save Page As...
, you will have to do exactly what you are proposing, posting $('body').html()
to your server and process it as text.
This link seems to explain exactly how to solve your problem.
Depending on your browser support requirements, you could use data URIs
Core for proof of concept (tested in Firefox 3.5.3):
document.write("<div id='content'><table><tr><td>Hola</td><td>Adios</td></tr></table></div>");
function extract(){
return document.getElementById('content').innerHTML;
}
function dataURI(s){
return 'data:application/vnd.ms-excel;base64,' + encode64(s);
}
document.write('<a href="' + dataURI(extract()) + '">open</a>');
I pulled base 64 encode/decode from examples online. Careful: the one I grabbed included a URI encode before base 64 encode that messed me up for a while.
You are getting close to the answer I thinks. The problem is that 'document.open(...)
' can only take standard mime-types such as 'text/html', 'text/plain' and a few others
And because of that your code should be:
<script>
document.write("<div id='content'><table><tr><td>Hola</td><td>Adios</td></tr></table></div>");
function saveAs(){
var sMarkup = document.getElementById('content').innerHTML;
var oNewDoc = document.open('text/html');
oNewDoc.write( sMarkup + "<hr>" );
oNewDoc.close();
}
</script>
<input type="button" value="Save as" onClick="saveAs()"/>
Hope this helps.
$(function(){
$('.bbutton').click(function(){
var url='data:application/vnd.ms-excel,' + encodeURIComponent($('#tableWrap').html() )
location.href=url
return false
})
})
.table{background:#ddd;border:1px solid #aaa;}
.table thead th{border-bottom:1px solid #bbb;}
.table tr td{background:#eee;border-bottom:1px solid #fff;
border-left:1px solid #ddd;text-align:center;}
.table tr:hover td{background:#fff;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id='tableWrap'><table style='width:98%;box-shadow:none;' class='table'>
<thead><th>id</th><th>Name</th><th>Address</th></thead>
<tr><td>1</td><td>Jyoti Telecom Services</td><td>http://www.tsjyoti.com</td></tr>
<tr><td>2</td><td>Recharge</td><td>http://recharge.tsjyoti.com</td></tr>
<tr><td>3</td><td>Bhuri Bharaj</td><td>http://bhuribharaj.tsjyoti.com</td></tr>
</table></div>
<p>Your download's ready as Excel Sheet <a href='#'class='bbutton'>Click Here for download</a></p>
If it's just a report, you could use server-side JavaScript to generate it, and then serve it up with whatever MIME type you need...
I dont think that sending your html to the server is a tricky solution. You just have to remember to give a link to your user to download this file. This can be done using a traditional POST, or even using AJAX. It depends on how you want your users to interact if your page.
Using traditional post, you could put all the html content in the value attribute of an input type hidden in your page, named "html_content" or something like that, and when the user clicks in the button "save" you send your user to another page with a link do the file. You send the html to server, a script creates a file in a filesystem with an unique name, and returns a download link.
Using AJAX, you just need to do an AJAX POST passing this variable, and then your script returns a download link, and you dynamically put it in your html - without reloading your page, like it was "only cliente side".
Either way, you'll return a link to the resource you just created in your filesystem with a html extension. Remember to generate unique names in your server for each generated file to avoid collisions.
Beware though that using innerHTML in IE 6 (I dont know if this is a IE family behavior or just about the 6 version) uppercases all tags and removes quotes from attributes. If you're planning to do some post processing in your html, be careful.
I dont know how jQuery or other JS libraries behaves in such situations. I would suggest using it though, they have plenty of browser compatibility checks to abstract all these hacks we use.
Here's my code to save the generated content[client-side] by the JavaScript to the local C: drive in MSWord[.doc] format.
<script>
document.write("<div id='content'><table><tr><td>Holaa</td><td>Adiosa</td></tr></table></div>");
function saveAs()
{
var wordObj=new ActiveXObject("Word.Application");
var docText;
var obj;
var textToWrite = document.getElementById('content').innerHTML;
if (wordObj != null)
{
wordObj.Visible = false;
wordDoc=wordObj.Documents.Add();
wordObj.Selection.TypeText(textToWrite);
wordDoc.SaveAs("C:\\Eureka.doc");
wordObj.Quit();
document.write("The content has been written to 'C:\\Eureka.doc'");//Print on webpage
}
}
</script>
<body>
<input type="button" value="Save in C:" onclick="saveAs()"/>
</body>
I quickly worked on ur issue and came up with this piece of code. Hope I understood your issue correctly.
The contraints in my code are
- File format is .doc and not .xls.
- Secondly, The file is saved in a static location and not the user specified location[can be optimized].
- And, the code uses ActiveX and I didnot check the working in server-side environment.
These need to be addressed in the upcoming versions. (:
Peace.
Is your javascript AJAX which fetches the document.writeln() content from the server, or are you already generating that content when the page is served to the user ? Because if it's the former, I see no reason why you can't save any variables / queries in the session of whatever server-side technology your using and then just generate the plain text stuff from those. Otherwise, you'll have to folow voyager's suggestion above.
Since you're using Ext JS, you probably have a Store object that provides data to the grid? You should be able to extract the data you need by walking through the Store, and then format it the way you want. I don't think scraping the data from the generated HTML is ideal.
Once you grab the data you need from the grid and format it into text, you could POST it to the backend to initiate a download (with Content-Disposition: attachment etc.)
If you're not concerned with being cross-browser, you can also use the data: URL scheme to initiate a download without involving the backend.
This plugin does the job. Tested on IE, FF & Chrome. https://github.com/dcneiner/Downloadify
来源:https://stackoverflow.com/questions/1479020/save-the-document-generated-by-javascript