tablas - obtener datos de una tabla html javascript
Usando un archivo local como fuente de datos en JavaScript (6)
Aquí está el código que usé para Firefox, que no es portátil, pero trabajos :
Como comentó OP, enablePrivilege()
ha quedado en desuso, esto debería considerarse utilizable. Pero como mi Firefox que usa el perfil anterior aún funciona con mi código, así que profundizo un poco en prefs.js
(ya que about:config
está ocultando estas configuraciones). Y aquí está la configuración que necesita para que funcione.
user_pref("capability.principal.codebase.p0.granted", "UniversalXPConnect");
user_pref("capability.principal.codebase.p0.id", "file://"); // path to the html file.
user_pref("capability.principal.codebase.p0.subjectName", "");
Y aquí va el código:
var File = function(file) {
netscape.security.PrivilegeManager.enablePrivilege(''UniversalXPConnect'');
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
if (!File.baseURI) {
File.baseURI = ios.newURI(location.href.substring(0, location.href.lastIndexOf(''/'')+1), null, null);
File.baseFolder = File.baseURI.QueryInterface(Components.interfaces.nsIFileURL).file.path;
}
var URL = ios.newURI(file, null, File.baseURI);
this.fptr = URL.QueryInterface(Components.interfaces.nsIFileURL).file;
}
File.prototype = {
write: function(data) {
netscape.security.PrivilegeManager.enablePrivilege(''UniversalXPConnect'');
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
foStream.init(this.fptr, 0x02 | 0x08 | 0x20, 0666, 0);
var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
.createInstance(Components.interfaces.nsIConverterOutputStream);
converter.init(foStream, null, 0, 0);
converter.writeString(data);
converter.close();
},
read: function() {
netscape.security.PrivilegeManager.enablePrivilege(''UniversalXPConnect'');
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
var cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
fstream.init(this.fptr, -1, 0, 0);
cstream.init(fstream, null, 0, 0);
var data = "";
// let (str = {}) { // use this only when using javascript 1.8
var str = {};
cstream.readString(0xffffffff, str);
data = str.value;
// }
cstream.close();
return data;
}
};
Fondo:
Quiero hacer una "aplicación" que use JavaScript / HTML solamente y se pueda abrir con un navegador directamente desde el sistema de archivos. Esta aplicación debe poder leer datos de otro archivo. Luego usaré JS para analizarlo y renderizar páginas. Como ejemplo simplificado, imagine que tengo un archivo CSV (descargue aquí) :
Mark Rodgers,[email protected],Accounting
[...]
Melissa Jones,[email protected],CEO
Quiero poder leer el archivo utilizando JS y usar los datos que contiene para generar mi página.
Lo que he logrado hasta ahora:
Demo (haga clic con el botón derecho -> "Guardar como" para guardar HTML en su computadora). También está disponible en jsfiddle en forma semi-quebrada (el diseño está roto, pero debería ser funcionalmente correcto).
Simplemente arrastre y suelte el archivo de texto CSV en el cuadro de arrastrar y soltar, o seleccione el archivo de texto usando el menú de archivos, y JavaScript leerá, analizará el archivo y llenará la tabla.
Esto se basa en la API FileReader; La mayor parte del trabajo pesado se realiza mediante esta función:
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.target.files || evt.dataTransfer.files; // FileList object.
var file = files[0];
// this creates the FileReader and reads stuff as text
var fr = new FileReader();
fr.onload = parse;
fr.readAsText(file);
// this is the function that actually parses the file
// and populates the table
function parse()
{
var table = document.getElementById(''emps'');
var employees = fr.result.split(''/n''); var c = 0;
for (var i in employees)
{
var employee = employees[i].split('','');
if (employee.length == 3)
{
var row = document.createElement(''tr'');
row.innerHTML = "<td>" + employee.join("</td><td>") + "</td>";
table.appendChild(row);
c++;
}
}
document.getElementById(''result'').innerHTML = ''<span>Added '' + c + '' employees from file: '' + file.name + ''</span>'';
}
}
Esto está casi bien, pero incita al usuario a cargar manualmente un archivo. Idealmente, debería poder cargarlo automáticamente, pero por razones de seguridad, ningún navegador lo permitirá ... todavía.
Requisitos de la solución:
Debe trabajar sin conexión; Es decir: no puede confiar en ningún servicio en línea. Esto también incluye servidores HTTP que se ejecutan en la máquina local. La idea es que esto se ejecute en cualquier computadora con solo un navegador instalado.
Debe funcionar cuando la página se abre con el
file:///
protocolo (es decir, una página HTML en el disco duro).No debe confiar en complementos de terceros (por ejemplo: Flash, Java, shudders ActiveX). Estoy bastante seguro de que esto probablemente no funcionaría de todos modos si la página está en el
file:///
Debe poder aceptar datos arbitrarios . Esto descarta la carga de un archivo en un formato de buen comportamiento que esté listo para el consumo como JSON.
Si funciona en Firefox o Chrome (idealmente ambos) está bien. También está bien confiar en las API experimentales
Sé de antemano cuál es el nombre del archivo, por lo que podría estar codificado en el propio HTML. Cualquier solución que me permita leer un archivo desde el disco está bien, no tiene que usar la API FileReader.
Entonces, si hay un truco inteligente para cargar un archivo en una página, también está bien (tal vez cargarlo en un iframe invisible y hacer que JS recupere el contenido); eso está bien también
Asegurándose de que el archivo se encuentre en el mismo directorio o en un subdirectorio, cargue el archivo con AJAX.
A diferencia de una etiqueta de script, obtendrás acceso a los contenidos.
Este es un ejemplo que utiliza datos JSON en un archivo externo que funciona localmente o en un servidor. Este ejemplo solo usa la configuración de idioma del navegador para cargar un <script> con html localizado y luego procesa su objeto json para restablecer los datos en las etiquetas indicadas con contenido localizado
<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<head>
<script>
function setLang(){
for (var i=0;i<items.length;i++){
term=document.getElementById(items[i].id)
if (term) term.innerHTML=items[i].value
}
}
var lang=navigator.userLanguage || navigator.language;
var script=document.createElement("script");
script.src=document.URL+"-"+lang.substring(0,2)+".js"
var head = document.getElementsByTagName(''head'')[0]
head.insertBefore(script,head.firstChild)
</script>
</head>
<body onload=''setLang()''>
<div id="string1" class="txt">This is the default text of string1.</div>
<div id="string2" class="txt">This is the default text of string2.</div>
</body></html>
Los archivos de datos para este aspecto son:
items=[
{"id":"string1","value":"Localized text of string1."},
{"id":"string2", "value":"Localized text of string2."}
];
pero puede usar cualquier parámetro para cargar condicionalmente el archivo apropiado (se insertará como la primera etiqueta en <head>, por lo que se podrá usar en cualquier lugar) y el formato JSON es capaz de manejar una gran variedad de datos. Es posible que desee cambiar el nombre de la función setLang a algo más apropiado y modificarlo para satisfacer sus necesidades, como ... para cada una, agrego una fila, luego agrego campos con los datos (parece que ya tiene un controlador en esa parte) y tu JSON se vería como:
items=[
{"fname":"john","lname":"smith","address":"1 1st St","phone":"555-1212"},
{"fname":"jane","lname":"smith","address":"1 1st St","phone":"555-1212"}
];
Si necesita preprocesar sus datos, awk es bastante práctico, sería algo como: (guestimate no probado)
awk ''BEGIN{FS=",";print "items=[/n"}
{printf "{/"fname/":/"%s/",/"lname/":/"smith/",/"address/":/"1 1st St/",/"phone/":/"555-1212/"},/n", $1, $2, $3, $4}
END{print "];"}'' file.csv > file.js
Edición: ahora que OP es más claro, solo los navegadores mozilla permiten XMLHttpRequest en el archivo: // fuera de la caja y Chrome (posiblemente otros navegadores basados en webkit) pueden configurarse para permitirlo. Sabiendo que NO puede funcionar en IE <10, puede:
var filePath = "your_file.txt";
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET",filePath,false);
xmlhttp.overrideMimeType(''text/plain'');
xmlhttp.send(null);
//maybe check status !=404 here
var fileContent = xmlhttp.responseText;
var fileArray = fileContent.split(''/n'')
var n = fileArray.length;
//process your data from here probably using split again for '',''
Dejo la variación de json-p inicial para otros que pueden tener un problema similar, pero tienen cierto control de su formato de datos, ya que funcionará en todos los navegadores compatibles con javascript. Sin embargo, si alguien conoce una forma de hacerlo funcionar para IE (aparte de ejecutar un pequeño servidor web), edítelo.
Edición 2:
Con los navegadores mozilla también puedes usar iframes.
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<head>
<script>
function showContents(frameObject){
alert(frameObject.contentDocument.body.innerHTML);
//replace with your code
}
</script>
</head>
<body onload=''showContents()''>
<iframe id="frametest" src="data.txt" onload="showContents(this);"
style="visibility:hidden;display:none"></iframe>
</body></html>
Esto se puede hacer fácilmente usando la clase XMLHttpRequest () de javascript:
function FileHelper()
{}
{
FileHelper.readStringFromFileAtPath = function(pathOfFileToReadFrom)
{
var request = new XMLHttpRequest();
request.open("GET", pathOfFileToReadFrom, false);
request.send(null);
var returnValue = request.responseText;
return returnValue;
}
}
...
var text = FileHelper.readStringFromFileAtPath ( "mytext.txt" );
Según tengo entendido, el contenido del archivo está completamente bajo su control y no tiene que ser un formato específico. ¿Y solo necesitas una forma de leer?
Usted podría declarar una función global "handleFile". En tu archivo externo el contenido debería ser así:
handleFile(''Mark Rodgers,[email protected],Accounting'');
Para "leer" el archivo, simplemente agregue un elemento de script con un atributo src correspondiente. En su función "handleFile", obtiene su contenido.
La ubicación del archivo probablemente tendrá que ser configurada inicialmente por el usuario, pero después de eso puede guardar la ubicación en localStorage o algo así.
Suponiendo que el archivo csv esté en el mismo directorio que la aplicación, cargaría el archivo con AJAX. Que yo sepa, uno puede obtener el archivo en formato de texto y luego analizarlo. Esto debería funcionar en IE y Firefox, pero no funciona en Chrome (a menos que uno ejecute Chrome con la configuración de línea de comando --allow-file-access-from-files
).