Vítejte na blog.vyvojar.cz Přihlásit | Registrovat | Pomoc

Maverick's blog

moje poznatky
Pouziti sablony z OpenOffice

Pri uprave jednoho projektu jsem narazil na nutnost upravovat dynamicky data v jiz nejakem vytvorenem template z OpenOffice. Tento projek byl psan jeste v asp a le nasledujici popisek je snad mozne pouzit i v klasickem .NET.

V jiz vytvorenem OpenOffice dokumentu mam bloky, ktere se maji prepisovat. Tyto bloky jsou oznaceny jako #ID_BLOKU#

Pripravenou sablonu z OpenOffice Writer (soubor *.odt) si nejdriv zmenim na soubor *.zip. Tento zip si rozbalim a vykopiruji z nej soubor content.xml a zase vratim do formatu odt.

Vykopirovany soubor content.xml si nakopiruji do zalozniho adresare pro upravy (zalozni adresar musi mit prava pro zapis, upravy i mazani)

· Dim oFSO
· Set oFSO = CreateObject("Scripting.FileSystemObject")
· if oFSO.FileExists(server.MapPath("/upload/content.xml")) then oFSO.DeleteFile(server.MapPath("/upload/content.xml"))
· CALL oFSO.CopyFile(server.MapPath("/template/content.xml"),server.MapPath("/upload/content.xml"), True)
· Set oFSO = nothing 

Tento soubor v zaloznim adresari (v tomto pripace "upload/content.xml") si oteviram jako text a klasickym replace provedu prepsani prislusnych bloku (#ID_BLOKU#) a ulozim.

Dany soubor *.odt si zkopiruji do nejakeho zalozniho souboru, ktery budu upravovat, a ktery take musim v kodu prenastavit z *.odt (OpenOffice Writer) na klasicky *.zip.

· Dim oFSO
· Set oFSO = CreateObject("Scripting.FileSystemObject")
· if oFSO.FileExists(server.MapPath("/upload/" & jmeno_word & ".zip")) then oFSO.DeleteFile(server.MapPath("/upload/" & jmeno_word & ".zip"))
· CALL oFSO.CopyFile(server.MapPath("/template/OO_Tempate.odt"),server.MapPath("/upload/OO_Tempate.zip"), True)
· Set oFSO = nothing 

Upraveny soubor content.xml nakopiruji do pripraveneho "/upload/OO_Tempate.zip" volanim nize uvedene funkce CopyFilesToZip.
v tomto pripade tedy :

On Error Resume Next
do until CopyFilesToZip(Server.MapPath("/upload/" & jmeno_word & ".zip"), Server.MapPath("/upload/" & id_kampane & "/content.xml")) = true
· Application.Wait(Now + TimeValue("0:00:01"))
loop
a tady je ta funkce:
function CopyFilesToZip(dest,source)
· Dim objApp
· Dim objZip
· dim ret 
· dim itemcount
·
· ret = false
· Set objApp = CreateObject("Shell.Application")
· Set objZip = objApp.NameSpace(dest)
·
· itemcount = objZip.items.Count
·
· if not objZip is nothing then
· · call objZip.CopyHere(source, 16)
· · ret = true
· end if
·
· On Error Resume Next
· do until objZip.items.Count = itemcount + 1
· · Application.Wait(Now + TimeValue("0:00:01"))
· loop
·
· Set objZip = nothing
· Set objApp = nothing
·
· CopyFilesToZip = ret
End function

Pak provedu zpetne prejmenovani souboru z zip na odt:

· Dim orFSO
· Dim orZipFile
· Set orFSO = CreateObject("Scripting.FileSystemObject")
· if orFSO.FileExists(Server.MapPath("/upload/OO_Tempate.odt")) then CALL orFSO.DeleteFile(Server.MapPath("/upload/OO_Tempate.odt"), True)
· CALL orFSO.CopyFile(Server.MapPath("/upload/OO_Tempate.zip"), Server.MapPath("/upload/OO_Tempate.odt"), True)
· CALL orFSO.DeleteFile(Server.MapPath("/upload/OO_Tempate.zip"), True)
· Set objFSO = nothing

A zbyva uz jen otevreni nebo download souboru:

Dim respFile 
respFile = "/upload/OO_Tempate.odt"
·
Response.Clear
response.buffer = true
·
Response.AddHeader "Content-Disposition", "attachment; filename=OO_Tempate.odt"
Response.ContentType = "application/x-zip-compressed"
·
dim wFSO
set wFSO = CreateObject("ADODB.Stream")
wFSO.Open
wFSO.Type = 1
wFSO.LoadFromFile(server.MapPath(respFile))
·
response.BinaryWrite(wFSO.Read)
Response.Flush
·
wFSO.Close
SET wFSO = nothing

Posted: 22. března 2006 9:34 by maverick | 3 Comments
Vedeno pod:
NETFramework 2.0 uziti BackgroundWorker
Tak mam zase jednu objevenou novinku (pro me) - uziti BackgroundWorker - pri programovani ve Visual Studiu .NET 2005.

Potreboval jsem ve Winformove aplikaci vytvorit nekolik Threadu, ktere by bezely na pozadi ale, tak aby v hlavnim formulari aplikace dochazelo k aktualizaci ProgressBaru. Pri pouziti klasickeho threadu bych musel celkem slozite zapracovavat. Kolega mi poradil pouziti komponenty, ktera je implementovana v .NET Frameworku 2.0 a jmenuje se BackgtoundWorker.
Udelal jsem tedy nasledujici:

1. Vytvoril jsem novou tridu (napr.: bwMain) jakop novy soubor.
2. Teto tride jsem nastavil, ze je dedena ze System.ComponentModel.BackkgroundWorker a je public
public class bwMain : System.ComponentModel.BackgrounWorker
{
...........
3. Nastavil jsem v teto pride private ProgressBar, do ktereho se bude dedit ProgressBar z hlavniho formulare.
private ProgressBar pbMain;
4. A vytvoril jsem kontruktor teto tridy
private bwMain(ProgressBar pbInp)
{
// nastavi do lokalniho ProgressBaru predavane hodnoty
this.pbMain = pbInp;
// nastaveni sledovani prubehu procesu
this.WorkerReportsProgress = true;
// nastaveni moznosti zastavit prubeh
this.WorkerSupportsCancellation = true;
// nastaveni procedur pro vykonavani pri Eventu - DoWork, ProgressChanged a RunWorkerCompleted
// DoWork - event ktery je volan pro startu (provadeni vlastniho kodu)
// ProgressChanged - event je volan pri zmene prubehu (pouziji pro inkrementaci progressbaru)
// RunWorkerCompleted - event, ktery je provaden pri ukoncovani
this.DoWork += new System.ComponentModel.DoWorkEventHandler(bwMain_DoWork);
this.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(bwMain_ProgressChanged);
this.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(bwMain_RunWorkerCompleted);
// a na konci konstruktoru spustim prubeh procesu
this.RunWorkerAsync();
}
5. Nasledne jsem deklaroval obsluhu eventu
void MakeKeywords_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
string msg = string.Empty;
if (e.cancelled)
msg = "Cancelled";
else if (e.error)
msg = "Error";
else
msg = "Finish";
MessageBox.Show(msg);
}
void MakeKeywords_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
// inkrementuje progressbar
pb.Increment(e.ProgressPercentage);
}

void MakeKeywords_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
// vyvola event pro zmenu prubehu
this.ReportProgress(1);
}
}
6. A v konecne fazi jsem v hlavnim formulari udelal nasledujici
// deklarace vlakna
private bwMain bw;
7. Ve funci pro vyvolani funkcnosti vlakna (napr.: OnButtonClick) jsem uz jen zavolal nasledujici
bw = new bwMain();
8. A do funkcnosti pri ukonceni aplikace jem pridal nasledujici kod
if ((bw != null) && (bw.IsBusy)) bw.CancelAsync();

Je to celkem jednoduche a a clovek nemusi zapracovavat mnoho funkcnosti. ;-)
Vyvojar.cz na prodej!