Monday, October 20, 2008

Notes View to PDF in 60 seconds

Watch the movie to see how to create a pdf of a view in 60 seconds.


I've produced a movie to demonstrate how easy it is to write an agent that creates a pdf of a view using my new library. I chose SuperNTF as it was the first database that had a flat view and a selection of documents. I copied and pasted enough entries to give me two pages so that you can see repeating headers. It's not quite as entertaining as 'Gone in 60 seconds' but does show you how quickly you can implement this in your own databases.


Below is the example code from the movie that simply dumps the content of a designated flat view to a table in a pdf. I've updated the library to Beta 7 to contain a minor enhancement to allow you to specify rows that are designated as headers. These header rows (yes you can specify more than one) are repeated on each page as the content forces a page break. Again, most of the heavy lifting is done by iText.


The Code

// the generic data object

PdfData data = new PdfData();

// where to put the file

PdfDocumentConfig config = new PdfDocumentConfig("Text",

"agent-test.pdf", "c:\\temp");


// getting the notes handles

AgentContext ctx = session.getAgentContext();

Database db = ctx.getCurrentDatabase();


// this is the view

View viewMembers = db.getView(" - insert your view alias here - ");

// get the column names for a header

Vector cols = viewMembers.getColumnNames();

// create a table based on the number of columns

TableElement tb = new TableElement(cols.size());

// start populating with the column names

RowElement rw = new RowElement();

for (int x = 0; x < cols.size(); x++) {

rw.addCell(new CellElement(cols.get(x).toString()));

}

// mark this as a table header to be repeated

rw.setTableHeading(true);

tb.AddRow(rw);

// start populating the table with the view data

ViewNavigator viewNav = viewMembers.createViewNav();

ViewEntry rowData = viewNav.getFirst();


while (!(rowData == null)) {

rw = new RowElement();

Vector viewCol = rowData.getColumnValues();


for (int y = 0; y < viewCol.size(); y++) {

rw.addCell(new CellElement(viewCol.get(y).toString()));

}

tb.AddRow(rw);

rowData = viewNav.getNext(rowData);

}

// add the table to the data object

data.add(tb);

// overide the default layout

LayoutElement layout =

new LayoutElement(LayoutElement.PAGESIZE_A4,

LayoutElement.ORIENTATION_LANDSCAPE,

10, 10, 10, 10, 10, 10);

// configure with the config, data and layout

PdfDocument pdf = new PdfDocument(config, data, layout);

// go

pdf.createDocument();


} catch (Exception e) {

e.printStackTrace();

} finally {

}


I've seen the move so how can I use this ?

1. Download Beta 7, and extract the updated jar file to a directory c:\lib

2. Download The JavaAgentPdf code

3. Create a new Java agent in your database, add the iText-2.0.8 jar and the new scius-pdfdoc.beta7.jar

3. Replace the JavaAgent code with the downloaded version and update the view name, pdf filename and pdf directory.


Enhancing the example further.

To keep this example short and under 30 lines, I have skipped of some of the things that you should add in for a production implementation, such as dealing with exceptions and checking that the domino objects are not null. However, for a proof-of-concept - it might be adequate. You would also need to write a few more lines to account for a categorised views, hidden columns and possibly the final enhancement would be to make the report look nice with some styles.


Stay tuned because the next post might have an example that produces a pdf that is a bit nicer on the eyes.


Update : The link to the zip file has changed. I found a bug with Beta7 and ParagraphElements.



5 comments:

  1. Hi Tony,

    This is good stuff--thanks for that. I've been working with iText lately. Do you know of a way to convert a document (that has already been generated) to PDF, including any rich text items?

    ReplyDelete
  2. Thanks Bill,

    I'm assuming you mean notes document to PDF including rich text fields.

    I've not looked into this or tried it (although I might be in the future) but there are a few place that I would suggest that you start.

    1. You can convert HTML to PDF using iText.
    2. There are the NotesRichText navigator set of classes that might be enough
    3. Try looking at DXL
    4. There are PDF tools from companies such as http://www.swingsoftware.com/
    5. There are RTF tools from
    http://www.geniisoft.com/showcase.nsf/Genii
    that might fill the gap.

    Of course if you just want the end users to print a document to PDF then really a PDF print driver is the way to go.

    I sort of imagine that creating PDFs with code would be behind the scenes from a user. Typically the PDF generated would be different from the data on screen.

    I hope that this points you in the right direction.

    ReplyDelete
  3. That's all good advice and definitely a place to start. I worked on this last week for a day, but I haven't had any time since to figure out if there is a good way to convert rich text.

    I've got an application that creates a report using the various rich text classes to generate a nice looking report. The next step was to generate an email with the report attached.

    We use Outlook for mail and although, I could still send a doclink, I just thought it would be interesting (more than anything) to see if I could convert the document to a PDF and attach it to an email for the end users.

    I will probably do it, but it's not a requirement at this point. If I get to it before you do, I will be sure to update you here.

    Thanks again for the great information and advice!

    ReplyDelete
  4. Anonymous6:59 am

    Really interesting article. Keep it coming. Thanks.

    ReplyDelete
  5. Anonymous8:49 am

    One way of doing the HTML-way is to use MSXML2.ServerXMLHTTP request to get the RT to HTML and then use the same technique described above.

    ReplyDelete