Du kan evt. prøve denne fil (*NB* Filen skal hedde '.hta' til efternavn ... ikke '.html' *NB*):
------------------ ExcellUpdater.hta - START ------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"
http://www.w3.org/TR/html4/loose.dtd"><html>
<script type="text/JavaScript">
resizeTo(960, 680);
</script>
<head>
<HTA:APPLICATION ID="MyApp"
APPLICATIONNAME="MyAppName"
VERSION = "0.1-Alpha"
CAPTION = "yes"
ICON = "ikon.ico"
BORDER = "thick"
SHOWINTASKBAR = "yes"
SINGLEINSTANCE = "yes"
MAXIMIZEBUTTON = "no"
WINDOWSTATE = "normal">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Excell Updater</title>
<style type="text/css">
body, html {
height: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
background: buttonface;
}
#display, #hiddenCont {
display: none;
width: 80%;
height: 500px;
margin: 20px auto;
padding: 20px;
border: 2px solid red;
}
#template {
display: block;
width: 80%;
height: 500px;
margin: 20px auto;
padding: 20px;
border: 2px solid blue;
}
.fullW {
width: 100%;
}
</style>
<script type="text/JavaScript" id="handyWrappers">
var d=document;
function gE(id){return d.getElementById(id)};
function gA(o,tag){return o.getElementsByTagName(tag)};
function cE(tag){return d.createElement(tag)};
</script>
<script type="text/JScript">
var maxEmptyRowsInEnd = 5;
var templateHidden = false;
var oTempl = null;
function hideShowTempl(hide) {
var oDispl, oTempl, oBtn = gE("btnToggle");
oDispl = gE("display");
oTempl = gE("template");
if (!templateHidden || hide) {
oTempl.style.display = "none";
oDispl.style.display = "block";
oBtn.value = "Vis Template"
templateHidden = true;
} else {
oTempl.style.display = "block";
oDispl.style.display = "none";
oBtn.value = "Skjul Template"
templateHidden = false;
}
}
function getTempl() {
var oHid, oTbl, oTbdy, oTr, oCont = gE("template");
oHid = gE("hiddenCont");
oHid.innerHTML = oCont.value;
oTbl = gA(oHid, "table")[0].cloneNode(true);
oTbdy = gA(oTbl, "tbody")[0];
oTr = oTbdy.removeChild( gA(oTbdy, "tr")[0] );
oTempl = {tbl:oTbl, tr:oTr};
oHid.removeChild( gA(oHid, "table")[0] );
}
function insRow(sVars) {
var aVars, oDispl, oHid, oTr, aTd, sTmp;
aVars = sVars.split(",");
oDispl = gE("display");
oHid = gE("hiddenCont");
oTr = oTempl.tr.cloneNode(true);
aTd = gA(oTr, "td");
for (var i=x=0; i<aTd.length-1; i++) {
if (aVars[i]!="") {
sTmp = aTd[i].innerHTML.replace(/%\{DATA\}%/g, aVars[i]);
sTmp = sTmp.replace(/%\{ESCAPE_DATA\}%/g, encodeURIComponent(aVars[i]));
aTd[i].innerHTML = sTmp;
x++;
}
else aTd[i].innerHTML = " ";
}
gA(oHid, "tbody")[0].appendChild(oTr);
return (x>0 ? true : false);
}
function finishExcell() {
var sTmp, oHid = gE("hiddenCont");
sTmp = oHid.innerHTML.replace(/<td/gi, "\t<td");
sTmp = sTmp.replace(/<([^\s]+)/gi, function($1){return $1.toLowerCase()});
sTmp = sTmp.replace(/><\/tr/g, ">\n</tr");
sTmp = sTmp.replace(/(<table>)|(<\/table>)|(<tbody>)|(<\/tbody>)/g, "");
gE("display").value = sTmp;
window.clipboardData.setData("Text",sTmp);
hideShowTempl(true);
}
</script>
<script type="text/vbscript">
Sub showData()
Dim sPath, xlsApp, xlsBook, xlsSheet
Dim oHid, nCheck, nCells, sVars, I, J
sPath = gE("selFile").value
set xlsApp = CreateObject("Excel.Application")
set xlsBook = xlsApp.Workbooks.Open(sPath)
set xlsSheet = xlsBook.Worksheets(1)
getTempl()
set oHid = gE("hiddenCont")
while (oHid.childNodes.length>0)
oHid.removeChild(oHid.firstChild)
Wend
oHid.appendChild(oTempl.tbl.cloneNode(true))
nCells = gA(oTempl.tr, "td").length
nCheck = 0
J = 0
while (nCheck < maxEmptyRowsInEnd)
sVars = ""
J = J + 1
For I = 1 To nCells
sVars = sVars & xlsSheet.Cells(J, I).Value & ","
Next
If (insRow(sVars) = false) Then
nCheck = nCheck + 1
End If
wend
set xlsSheet = Nothing
xlsApp.Quit()
set xlsApp = Nothing
finishExcell()
End Sub
</script>
</head>
<body>
<table class="fullW">
<tbody>
<tr>
<td><input id="selFile" class="fullW" type="file"></td>
<td style="width:90px"><button onclick="showData()">Udskriv</button></td>
<td style="width:135px"><button id="btnToggle" onclick="hideShowTempl()" style="width:100%">Skjul Template</button></td>
</tr>
</tbody>
</table>
<textarea id="template">
<table>
<tbody>
<tr>
<td class="left">En tekst om:<br><b>%{DATA}%</b></td>
<td class="center">Et link til: <a href="
http://www.domain.dk/sti/til/fil.php?noget=%{ESCAPE_DATA}%">%{DATA}%</a></td> <td class="right">%{DATA}%</td>
</tr>
</tbody>
</table>
</textarea>
<textarea id="display"></textarea>
<div id="hiddenCont"></div>
</body>
</html>
------------------ ExcellUpdater.hta - SLUT ------------------
Filen er en HTA-fil, hvilket er en special-instans af IE - med andre sikkerheds-regler. Derfor kan man uden problemer afvikle de fleste ActiveX-komponenter - herunder 'Excel.Application' objektet, som er installeret på PC'en, hvis Office-pakken er det.
Jeg kan bedst lide at skrive JS, men IE har en forfærdelig elendig garbage-collection i JS. Det betyder, at objekterne ikke bliver ordentligt destrueret, når de har været brugt - hvilket er noget skidt, hvis du læser mange xls-filer i én session.
Derfor har jeg valgt at skrive selve ActiveX-delen i VBScript, der er bedre til at 'vaske op' efter sig.
For at bruge programet, dobbelt-klikker du som vanligt på filen.
Derefter klikker du 'Gennemse...' (eller 'Browse...') og vælger den fil, du vil læse. Når det er gjort, klikker du 'Udskriv'.
Programmet læser nu filen og fylder data fra cellerne ned i skabelonen, hvor der står '%{DATA}%'. Du kan også bruge '%{ESCAPE_DATA}%', som escaper data, så de kan bruges i en URL.
Skabelonen er den kode, du ser, når du åbner filen. Jeg har testet med en xls-fil med tre kolonner - hvorfor skabelonen også har tre kolonner.
Tabel-koden, der er hårdkodet ind i program-koden ovenfor, kan du selv finde og rette, men du kan også rette den 'på forsiden' af programmet. Betragt den kode, du vælger at have hårdkodet som din default-skabelon.
Programmet skriver tabellens rækker ud - og såsnart du kan se dem, er de automatisk blevet kopieret til udklipsholderen. Du kan blot paste dem ind i en HTML-fil - i stedet for de bestående rækker.
Koden kunne sagtens gøres mere 'sexy', men skidtet virker. Jeg ved godt, du gerne ville afvikle det 'realtime' - men så må du klare det på serveren (og jeg ved ikke, om det lader sig gøre på andet end en Windows-server).
Håber, dette i det mindste kan gøre det nuværende arbejde lidt lettere ;o)