Introduction
In addition to Fixed layout API,
the Apitron PDF Kit for .NET component provides a Flow layout API which
supports css-like styling, and is very similar to HTML in terms of elements
structure. The difference between the two is described in the following blog
post.
The Flow layout API also supports
XML export and import, making it possible to create XML templates for documents
or PDF forms and later use them as a base, adding the necessary data or filling
the PDF fields for example.
In this article we'll show how to work with XML templates and produce PDF documents using Flow layout API.
In this article we'll show how to work with XML templates and produce PDF documents using Flow layout API.
Creating the base template
Usually, we start with the
template by creating it from code, so it’s the code first approach. Of course,
it’s possible to create the XML template from scratch, but starting from code
is a bit more convenient and speeds up the initial development.
private static void CreateTemplate()
{
//
create resource manager and register image resource
ResourceManager resourceManager = new ResourceManager();
resourceManager.RegisterResource(new Image("logo", "../../images/logo.png", true));
//
create document object and register styles
FlowDocument doc = new FlowDocument()
{
Margin = new Thickness(30, 20, 30, 20)
};
{
Margin = new Thickness(30, 20, 30, 20)
};
// style
for image logo
doc.StyleManager.RegisterStyle(".logo", new Style()
{
Margin = new Thickness(0, 0, 10, 10)
});
{
Margin = new Thickness(0, 0, 10, 10)
});
// style
for note below the header
doc.StyleManager.RegisterStyle(".headerNote", new Style()
{
Display = Display.InlineBlock,
Align = Align.Justify
});
// style
for header
doc.StyleManager.RegisterStyle(".header",
new Style()
{
Font = new Font(StandardFonts.HelveticaBold,
18),
Display = Display.InlineBlock,
Align = Align.Right,
VerticalAlign = VerticalAlign.Bottom,
Margin = new Thickness(0, 0, 0, 10)
});
// style
for unordered list
doc.StyleManager.RegisterStyle(".ul", new Style()
{
ListStyle = ListStyle.Unordered,
ListMarker = ListMarker.Circle,
ListMarkerPadding = new Thickness(0, 0, 10, 0),
Margin = new Thickness(0, 20, 0, 0)
});
//style
for list items
doc.StyleManager.RegisterStyle(".ul > *", new Style()
{
ListStyle = ListStyle.ListItem,
Margin = new Thickness(0, 10, 0, 10)
});
doc.Add(new Image("logo") {Class = "logo"});
doc.Add(new TextBlock("Sample Interview
Questions for Candidates")
{
Class = "header"
});
{
Class = "header"
});
doc.Add(new Br());
doc.Add(new TextBlock(
"To
help facilitate the interview process the Human Resources Department " +
"has
compiled a list of questions that might be used during the phone " +
"and/or
on-campus interviews. " +
"Some
of the questions deal with the same content, " +
"but
are phrased differently while other questions may not pertain " +
"to
a specific discipline; however all of the questions" +
"
are unbiased and appropriate to ask. We hope you'll find " +
"this
helpful.") {Class = "headerNote"});
// add questions list
Section list = new Section() {Class = "ul"};
list.Add(new TextBlock("What do you consider
to be one of your greatest
achievements? Why?"));
achievements? Why?"));
list.Add(new TextBlock("What's the latest
technology innovation you're aware of?"));
list.Add(new TextBlock("What motivates you to
do your best?"));
list.Add(new TextBlock("Why did you choose to
apply to this position?"));
list.Add(new TextBlock("What do you consider
to be your particular strength(s)?"));
list.Add(new TextBlock("What areas would you
like to improve during the next two
years?"));
years?"));
list.Add(new TextBlock("Why are you
interested in working in the COMPANY?"));
list.Add(new TextBlock("What do you consider
to be your particular weakness(es)?"));
list.Add(new TextBlock("What is the most
exciting thing you've been working on
recently?"));
recently?"));
list.Add(new TextBlock("Do you like to be a
part of the team or prefer to work
separately?"));
separately?"));
list.Add(new TextBlock("Are you able to work
remotely?"));
list.Add(new TextBlock("Why should we hire
you?"));
list.Add(new TextBlock("Where do you see
yourself in a two years?"));
list.Add(new TextBlock("Why are you leaving
your current job?"));
list.Add(new TextBlock("What type of work
environment do you prefer?"));
doc.Add(list);
//
export as PDF
using (Stream stream = File.Create("out.pdf"))
{
doc.Write(stream, resourceManager);
}
//
create XML template
using (Stream stream = File.Create("template.xml"))
{
doc.SaveToXml(stream, resourceManager);
}
}
As you can see from the code
sample above, we create a very simple questionnaire for an imaginable HR department.
First come the company logo and header, then additional note, and lastly a list
of questions. When the document is filled up, we create a PDF for previewing
and corresponding XML file for later use.
The generated document looks as follows:
Pic. 1 Created PDF document
|
The resulting XML template
<?xml version="1.0" encoding="utf-8"?>
<FlowDocument xmlns="Apitron.PDF.Kit.FlowLayout.v1">
<Resources>
<Image resourceId="logo" fileName="../../images/logo.png" />
</Resources>
<Styles>
<Style selector="flowdocument">
<Color value="Black" />
</Style>
<Style selector="grid">
<InnerBorder thickness="1" />
<InnerBorderColor value="Black" />
</Style>
<Style selector=".logo">
<Margin value="0,0,10,10" />
</Style>
<Style selector=".headerNote">
<Align value="Justify" />
<Display value="InlineBlock" />
</Style>
<Style selector=".header">
<Align value="Right" />
<Display value="InlineBlock" />
<Font resourceId="Helvetica-Bold" size="18" />
<Margin value="0,0,0,10" />
<VerticalAlign value="Bottom" />
</Style>
<Style selector=".ul">
<ListMarker value="Circle" />
<ListMarkerPadding value="0,0,10,0" />
<ListStyle value="Unordered" />
<Margin value="0,20,0,0" />
</Style>
<Style selector=".ul > *">
<ListStyle value="ListItem" />
<Margin value="0,10,0,10" />
</Style>
</Styles>
<Elements>
<Image>
<Properties>
<Class value="logo" />
<ResourceId value="logo" />
</Properties>
</Image>
<TextBlock>
<Properties>
<Class value="header" />
<Text value="Sample Interview Questions for Candidates" />
</Properties>
</TextBlock>
<Br />
<TextBlock>
<Properties>
<Class value="headerNote" />
<Text value="To help facilitate the interview process the Human
Resources Department has compiled a list of questions that might be used during
the phone and/or on-campus interviews. Some of the questions deal with the same
content, but are phrased differently while other questions may not pertain to a
specific discipline; however all of the questions are unbiased and appropriate
to ask.
We hope you'll find this helpful." />
</Properties>
</TextBlock>
<Section>
<Elements>
<TextBlock>
<Properties>
<Text value="What do you consider to be one of your greatest
achievements? Why?" />
</Properties>
</TextBlock>
...questions
<TextBlock>
<Properties>
<Text value="What type of work environment do you prefer?" />
</Properties>
</TextBlock>
</Elements>
<Properties>
<Class value="ul" />
</Properties>
</Section>
</Elements>
<Properties>
<Margin value="30,20,30,20" />
</Properties>
</FlowDocument>
You see that the resulting XML
contains styles and values for elements’ properties as well as the path to the
image resource registered in document’s resource manager. One of the benefits
of having the XML template is the ability to alter documents without
recompiling the app. See the next section to learn how to do it.
Changing template
Let’s design our app to accept
XML templates as command line argument; in order to do it we’ll implement the
entry point of the program as follows:
static void Main(string[] args)
{
if (args == null || args.Length==0)
{
CreateTemplate();
}
else
{
LoadTemplate(args[0]);
}
}
and add
the template loading part:
private static void LoadTemplate(string templatePath)
{
using (Stream stream = File.OpenRead(templatePath),
outputStream = File.Create("fromTemplate.pdf"))
{
ResourceManager resourceManager = new ResourceManager();
FlowDocument doc = FlowDocument.LoadFromXml(stream, resourceManager );
doc.Write(outputStream,
resourceManager);
}
}
After that, let’s add new content to the xml template we
have. Insert the following piece of XML that creates new textblock in the Elements collection of the Section element:
<TextBlock>
<Properties>
<Color value="Red" />
<Text value="Do you have any questions for us?" />
</Properties>
</TextBlock>
It adds new question and makes it drawn in red color.
Execute the program with command line parameter “template.xml” and new PDF file
will be created for you.
The complete example can be found
in our GitHub repository (link).
Resulting PDF document generated from xml template looks as
follows:
Pic. 2 Modified PDF file created from XML
template
|
Conclusion
Apitron PDF Kit for .NET
component is a reliable PDF library that can be used to process PDF documents
of any origin and manipulate their content in any desired way. Its easy to
learn and well-structured API speeds up the development process and helps to
achieve the desired results saving development time for other tasks.
Downloadable version of this article can be found by the following link [PDF].
Downloadable version of this article can be found by the following link [PDF].
No comments:
Post a Comment