Egna utskrifter
Man kan skriva egna utskrifter som sedan går att nå från applikationen. Detta är en kort sammanfattad beskrivning av hur man kan göra detta.
Skapa utskriften
Skapa följande tre filer:
[bankenab]
[bkplugins]
[utskrifter]
UtskriftMinSida.java
MinSida.java
MinSida.xml
Katalogstrukturen ovan beskriver package/namespace-strukturen och den är godtycklig, den bestämmer du själv. Filerna ska ligga i något programbibliotek som är nåbart av boendekalkylen.
UtskriftMinSida.java (utskriftsspecifik DTO)
Denna fil ska innehålla attribut/medlemsvariabler som kan användas för data som ska kunna tilldelas vid tex ett webservice-anrop eller tilldelas via konfigurationsfilen. Dvs något som enkelt ska gå att ändra utan att kompilera om, tex en informationstext. Har man tre utskrifter som är mer eller mindre identiska så kan man i praktiken ha samma utskrift som sedan styrs med parametrar som finns i denna klass. Denna klass ska ärva capitex.boendekalkyl.datastrukturer.utskrifter.clsUtskrift. Normalt sett så räcker det med en tom sådan klass
Exempelkod, c#
namespace
bankenab.bkplugins.utskrifter {
public
class
UtskriftMinSida:capitex.boendekalkyl.datastrukturer.utskrifter.clsUtskrift {
}
}
MinSida.java (codebehind)
Denna fil sköter logiken som överför information från datastrukturerna till själva utskriftsmallen, här kan man tex summera fält, räkna ut genomsnitt på vissa belopp, dölja/visa olika delar av utskriften beroende på indatat.
Klassen ska ärva: capitex.boendekalkyl.utskrifter.Utskriftssida
Klassen ska implementera: capitex.componentmodel.IUserControl
Följande funktioner ska implementeras:
getUtskriftsnamn() - ska returnera namnet på utskriften som visas i utskriftsdialogen
OnInit() - Här ska mallen läsas in så mallens kontrollträd skapas upp som sedan manipuleras i funktionen setData
setData() - in till denna funktion kommer all tillgänglig data, det är här man överför data till utskriftsmallen
Exempel i c#
namespace
bankenab.bkplugins.utskrifter {
public
class
MinSida:capitex.boendekalkyl.utskrifter.Utskriftssida, capitex.componentmodel.IUserControl {
public
capitex.componentmodel.Generic mainblock;
public
override
String getUtskriftsnamn() {
return
"Min sida"
;
}
public
override
void
setData(capitex.boendekalkyl.utskrifter.DataFoerEnSida indata) {
mainblock.setInnerText(indata.HandlaeggareNamn);
}
public
MinSida(capitex.dom.Element el):
base
(el) {
}
protected
override
void
OnInit() {
base
.OnInit();
System.IO.Stream dotnet_stream;
java.io.InputStream java_inputstream;
java.io.InputStreamReader java_stream_Reader;
java.io.BufferedInputStream buffered_stream;
dotnet_stream = (
typeof
(Sammanstaellning)).Assembly.GetManifestResourceStream(
"bankenab.bkplugins.utskrifter.MinSida.xml"
);
java_inputstream =
new
cpx.util.StreamWrapper(dotnet_stream);
buffered_stream =
new
java.io.BufferedInputStream(java_inputstream);
java_stream_Reader =
new
java.io.InputStreamReader(buffered_stream);
this
.LoadChildren(
this
, java_stream_Reader,
false
);
}
}
}
I java blir OnInit enklare, där räcker följande:
protected
void
OnInit() {
super
.OnInit();
this
.LoadChildrenFromResource(
"MinSida.xml"
);
}
MinSida.xml (markup)
Denna fil är själva utskriftsmallen som är ett kontrollträd med tex FO-kod som sedan laddas in i funktionen OnInit() och manipuleras i setData()
<?
xml
version
=
"1.0"
encoding
=
"iso-8859-1"
?>
<
bankenab
.bkplugins.utskrifter.MinSida
xmlns:fo
=
"http://www.w3.org/1999/XSL/Format"
>
<
fo
:block
ID
=
"mainblock"
>Hello World</
fo
:block>
</
bankenab
.bkplugins.utskrifter.MinSida>
I denna xml-fil skriver man fo-kod. Ger man ett element ett ID (med stora bokstäver) så kan man deklarera en publik medlemsvariabel med samma namn i codebehind-klassen och då kan man komma åt elementet för att tex tilldela InnerText eller dölja/visa den med funktionen setVisible(). Hur FO-koden skrivs för övrigt går jag inte in närmare på här utan hänvisar till Internet där det finns mycket att läsa om detta. Tänk dock på att detta system inte genomför någon XSL-transformation på indata och utskriftsmallen så när fo-exempel på nätet pratar om xsl:value-of för att hämta ut data mm så har detta inte något med denna lösning att göra. Detta är alltså ren FO som sedan kan styras programmatiskt innan FO-koden konverteras till PDF.
Root-elementet i en utskrift måste alltid vara fo:block med ett ID samt en tillhörande publik medlemsvariabel (detta är för att utskriftmotorn letar upp detta block och lägger till sid-brytning efter detta block vid behov)
Tips för c#
För att hantera streams i c# kan det vara lämpligt med en klass som wrappar en java-stream eftersom det är java-streans som applikationen använder, exempelkod för detta kommer här:
namespace
cpx.util {
public
class
StreamWrapper: java.io.InputStream {
System.IO.Stream _s;
public
StreamWrapper(System.IO.Stream s) {
_s = s;
}
public
override
int
read() {
return
_s.ReadByte();
}
public
override
int
read(
byte
[] b) {
int
l = _s.Read(b, 0, b.Length);
if
(l == 0) {
return
-1;
}
return
l;
}
public
override
int
read(
byte
[] b,
int
off,
int
len) {
int
l;
l=_s.Read(b, off, len);
if
(l == 0) {
return
-1;
}
return
l;
}
}
}
Aktivera utskriften
Detta görs i capitex_config.xml enligt följande exempel:
Java
<
capitex_boendekalkyl_valbara_utskrifter
>
<
dokument
inkludera
=
"true"
ID
=
"UtskriftMinSida"
foervald
=
"true"
>
<
dataklass
>bankenab.bkplugins.utskrifter.UtskriftMinSida</
dataklass
>
<
printklass
>bankenab.bkplugins.utskrifter.MinSida</
printklass
>
</
dokument
>
</
capitex_boendekalkyl_valbara_utskrifter
>
Dotnet
I dotnet måste man ange assemblynamnet också, detta exempel antar att utskriften ligger i ett assembly som heter MittAssembly, dvs filen MittAssembly.dll i bin-katalogen.
<
capitex_boendekalkyl_valbara_utskrifter
>
<
dokument
inkludera
=
"true"
ID
=
"UtskriftMinSida"
foervald
=
"true"
>
<
dataklass
>bankenab.bkplugins.utskrifter.UtskriftMinSida, MittAssembly</
dataklass
>
<
printklass
>bankenab.bkplugins.utskrifter.MinSida, MittAssembly</
printklass
>
</
dokument
>
</
capitex_boendekalkyl_valbara_utskrifter
>
Anropa Utskriften
Det finns många sätt att generera utskriften, se tex mer information om webservicen för utskrifter samt service-funktionerna som man kan nå från plugins mm. Detta exempel jag tar upp här är ett mer avancerat exempel när man har tillgång till alla boendekalkylens dll'er i sin egna applikation. (man använder tex bara boendekalkylen som ett programbibliotek och har skapat resten av gränssnittet själv, men man har valt att inte anropa via webservice)
Att anropa den separat inprocess i c#, kan se ut så här:
capitex.dotnet.j2eewrapper.DotnetRequest req =
new
capitex.dotnet.j2eewrapper.DotnetRequest(System.Web.HttpContext.Current);
capitex.dotnet.j2eewrapper.DotnetResponse resp =
new
capitex.dotnet.j2eewrapper.DotnetResponse(System.Web.HttpContext.Current);
capitex.dotnet.j2eewrapper.DotnetServletContext ct =
new
capitex.dotnet.j2eewrapper.DotnetServletContext();
capitex.ctx.j2ee.Context ctx =
new
capitex.ctx.j2ee.Context(req, resp, ct);
capitex.boendekalkyl.utskrifter.KalkylMedUtskrift k =
new
capitex.boendekalkyl.utskrifter.KalkylMedUtskrift(ctx,
this
);
k.setSoekvaegTillInstaellningsfiler(
this
.SoekvaegTillInstaellningar);
k.setBeraekningsAAr(mBeraekningsaar);
capitex.boendekalkyl.datastrukturer.utskrifter.clsResUtskrift utskres;
capitex.boendekalkyl.datastrukturer.utskrifter.clsSkapaUtskrift skapautskrift =
new
capitex.boendekalkyl.datastrukturer.utskrifter.clsSkapaUtskrift();
capitex.boendekalkyl.datastrukturer.@
in
.clsIn clsIn =
new
capitex.boendekalkyl.datastrukturer.@
in
.clsIn();
// Fyller på clsIn utifrån inmatade belopp
OEverfoerFraanFaeltTillDatastruktur(clsIn);
skapautskrift.InmatadeUppgifter = clsIn;
skapautskrift.Dokumentformat =
"application/pdf"
;
skapautskrift.Utskrifter =
new
capitex.boendekalkyl.datastrukturer.utskrifter.clsUtskrift[] {
new
bankenab.bkplugins.utskrifter.UtskriftMinSida()
};
utskres = k.SkapaUtskrift(skapautskrift);
Response.Clear();
Response.ContentType=
"application/pdf"
;
Response.AddHeader(
"Content-Disposition"
, "attachment;
filename=KonsumentverketsBudgetkalkyl.pdf");
Response.OutputStream.Write(utskres.DokumentOEvrigaFormat, 0, utskres.DokumentOEvrigaFormat.Length);
Response.End();
Dela upp utskriften i komponenter
Fo-dokument kan snabbt bli stora och oöverskådliga, för att förenkla utvecklingen och förvaltningen av utskriften så kan man dela upp dokumentmallen i flera delkomponenter. Varje delkomponent fungerar som ovan med en mallsida och en codebehind. Skillnaden är att delkomponenten ärver från en annan klass och inte behöver någon tillhörande DTO-klass.
Använda en komponent, c#
<?
xml
version
=
"1.0"
encoding
=
"iso-8859-1"
?>
<
bankenab
.bkplugins.utskrifter.MinSida
xmlns:fo
=
"http://www.w3.org/1999/XSL/Format"
xmlns:kp
=
"urn:bankenab.bkplugins.utskrifter.komponenter, MittAssembly"
>
<
fo
:block
ID
=
"mainblock"
>
<
kp
:Exempelkomponent />
</
fo
:block>
</
bankenab
.bkplugins.utskrifter.MinSida>
Använda en komponent, java
<?
xml
version
=
"1.0"
encoding
=
"iso-8859-1"
?>
<
bankenab
.bkplugins.utskrifter.MinSida
xmlns:fo
=
"http://www.w3.org/1999/XSL/Format"
xmlns:kp
=
"urn:bankenab.bkplugins.utskrifter.komponenter"
>
<
fo
:block
ID
=
"mainblock"
>
<
kp
:Exempelkomponent />
</
fo
:block>
</
bankenab
.bkplugins.utskrifter.MinSida>
Ger man komponentinstansen ett ID så kan man deklarera instansen som en publik medlemsvariabel i codebehind-klassen och man kan då komma åt att anropa funktioner mm i komponenten (dvs på samma sätt som vi gjort med mainblock i exemplet högre upp på sidan, men man ska använda komponentens klassnamn istället för capitex.componentmodel.Generic)
Exempelkod för en komponent, c#
<?
xml
version
=
"1.0"
encoding
=
"iso-8859-1"
?>
<
bankenab
.bkplugins.utskrifter.komponenter.Exempelkomponent
xmlns:fo
=
"http://www.w3.org/1999/XSL/Format"
xmlns:kp
=
"urn:bankenab.bkplugins.utskrifter.komponenter"
>
<
fo
:block>
Detta är en komponent
</
fo
:block>
</
bankenab
.bkplugins.utskrifter.komponenter.Exempelkomponent>
Exempelkomponent, Codebehind:
I detta exempel har vi gjort en liten hjälpfunktion som hämtar xml-resursen, koden i den är samma som för själva utskriftssidan, se ovan.
namespace
bankenab.bkplugins.utskrifter.komponenter {
public
class
Exempelkomponent:capitex.componentmodel.Control, capitex.componentmodel.IUserControl {
public
ExempelKomponent(capitex.dom.Element el):
base
(el) { }
protected
override
void
OnInit() {
base
.OnInit();
this
.LoadChildren(
this
, PrintUtil.GetResourceStream(
this
,
"bankenab.bkplugins.utskrifter.komponenter.Exempelkomponent.xml"
),
false
);
}
}
}