4 replies [Last post]
btanner
Offline
Joined: 2010-04-13

Hi guys. I realize I'm using the software for free, so I'm not sure if it's really appropriate to post questions/bugs/misunderstandings here.

I'll try it and you can let me know what you think.

So I have a simple template with some input fields for substitution and some conditional sections. I wanted to give myself the option of generating multiple output formats in a single go, so I have a checkbox each for Word, OpenOffice, and PDF. My quick prototype code looks like this:

DataProvider theDataProvider=dpb.getDataProvider();

if(createODT.isSelected()){
DocumentProcessor.renderDoc(new File("../FirePlan.odt"), new File("output.odt"), theDataProvider);
}
if(createPDF.isSelected()){
DocumentProcessor.renderDoc(new File("../FirePlan.odt"), new File("output.pdf"),theDataProvider);
}
if(createMSWord.isSelected()){
DocumentProcessor.renderDoc(new File("../FirePlan.odt"), new File("output.doc"), theDataProvider);
}

The problem is that whatever format I do first works like a charm, but the following ones do not. Perhaps the DataProvider keeps some sort of state and needs to be reset? Or perhaps I have to create a whole new DataProviderBuilder for each document I want to output? I can do the latter, but it seems like a waste so I wanted to check if this is expected behaviour.

And I did try to actually call dpb.GetDataProvider() separately for each call to renderDoc, same problem.

Thanks in advance!

modman
Offline
Joined: 2010-11-25
Please provide more information

Hello BT.

Your logic is ok, and this does work. As for it being free - that's no excuse for a program to fail so we don't expect Docmosis to let you down. Don't worry about posting bugs here, if your posting is not appropriate or you offend us too much we'll delete your post ;)

What you need to do is tell us what is going wrong in more detail. Your description of the problem "the following ones do not [work like a charm]" doesn't tell us enough to help you work out the problem. Are you:

  1. Getting an exception
  2. Getting an empty resulting file
  3. Getting a document but with unexpected content

?

Also, depending on what you need to achieve, it is more efficient to render the documents in all selected formats in a single call and return a zip file. Docmosis will do this automtically if you send it a ConversionInstruction with multiple formats. See the code inside example1 in the download bundle. The way you are doing it matches the code in example 3 in which it renders the document in different formats using separate render calls.

btanner
Offline
Joined: 2010-04-13
Blank fields in result file

Ok, good call, sorry about the vagueness.

I'm just trying to get some simple prototypes working before I am totally committed to the product, so I confess I've not invested the time learning all the different ways to do things. The code I posted above seemed like a straightforward way to get started so I just started there. Let's stick with that for now, if you don't mind, in case it is actually a bug (cause I'm sure you'd like to know about it).

If I check multiple boxes in my application (multiple output formats), then whichever gets rendered first renders correctly. The others (from within the Java app) appear to render ok. No exceptions, errors, or warnings. They successfully produce an output file in the appropriate location. Within that file, all of the conditional sections are missing (as if their conditions were evaluated as False), and all of the fields that should be filled in are blank/empty.

modman
Offline
Joined: 2010-11-25
Auto-Cleanup is responsible
Hello BT. The source of the problem is that Docmosis automatically cleans up the DataProvider after a render. You can prove this by doing a toString() on it before and after the DocumentProcessor.render() call. All built-in DataProviders are cleaned up automatically because of the risk of leaks (particularly with image handles). To take control of this you need to use a different renderDoc() method, one that takes a ConversionInstruction. The instruction can specify that you don't want the DataProvider cleaned up during the render. You will be responsible for calling cleanup() when you are ready. Here's an example:
    		// upload the template (assuming your templates are in a "templates" folder) 
    		new DropStoreHelper(TemplateStoreFactory.getStore()).process(new File("templates"));

    		// identify the template
    		TemplateIdentifier templateId = new TemplateIdentifier("FirePlan.odt");

    		// set the basic instruction
    		ConversionInstruction instruction = new ConversionInstruction();

    		// turn off cleanup so you can re-use the data provider
    		instruction.setCleanupDataProvider(false);
    		
    		DataProvider dp = dpb.getDataProvider();
    		
    		// repeat this for as many formats as you wish to output
    		// create the destination
    		try {
	    		instruction.setConversionFormats(new ConversionFormat[]{ConversionFormat.FORMAT_PDF});
	    		FileOutputStream fout = new FileOutputStream(outputFile);
	    		try {
	    			DocumentProcessor.renderDoc(templateId, dp, instruction, fout);
	    		} finally {
	    			if (fout != null) {
	    				fout.close();
	    			}
	    		}
    		} finally {
                        // manual cleanup of DataProvider
    			if (dp instanceof Cleanable) {
    				((Cleanable)dp).cleanup();
    			}
    		}
This is obviously a bit more code, since you can use the simpler version of renderDoc(). We will add a new renderDoc() method in our next release to facilitate this.
modman
Offline
Joined: 2010-11-25
Confirmed for Release 2.2
Hello BT. Confirmed with release 2.2 that you will be able to add a parameter to your existing code: DocumentProcessor.renderDoc(new File("../FirePlan.odt"), new File("output.odt"), theDataProvider, false);