opensagres / xdocreport

XDocReport means XML Document reporting. It's Java API to merge XML document created with MS Office (docx) or OpenOffice (odt), LibreOffice (odt) with a Java model to generate report and convert it if you need to another format (PDF, XHTML...).
https://github.com/opensagres/xdocreport
1.21k stars 371 forks source link

Android Implementation Corrupted ODT File #418

Open d-j-kendall opened 4 years ago

d-j-kendall commented 4 years ago

Problem

I am attempting to get use XDocReport to automatically generate documents from templates in android. My code works fine as a unit test (I get the expected result), but as soon as I port it over to android I get and error stating "Can't create default XMLReader".

I followed a suggestion to manually set the system's SAX driver. After setting the system property, the code ran fine, but when I pull the document from my android device open office says the document is corrupted.

It would be convenient if there were a way to manually set your parser for each document.

Is there a a way to fix this?

Errors

fr.opensagres.xdocreport.core.XDocReportException: org.xml.sax.SAXException: Can't create default XMLReader; is system property org.xml.sax.driver set?
at fr.opensagres.xdocreport.document.preprocessor.sax.SAXXDocPreprocessor.preprocess(SAXXDocPreprocessor.java:77)
at fr.opensagres.xdocreport.document.preprocessor.sax.SAXXDocPreprocessor.preprocess(SAXXDocPreprocessor.java:47)
... 35 more

enter image description here

Code

        System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver");
        context = InstrumentationRegistry.getInstrumentation().getTargetContext();
        in = context.getAssets().open("doc_templates/test_report_template.odt");

        JobInfo jobInfo = new JobInfo();
        jobInfo.setCustomerId("Customer Id");
        jobInfo.setCustomerName("Customer Name");
        jobInfo.setJobNbrId("Job # 1");
        jobInfo.setPurchaseOrderId("PO # 3");
        jobInfo.setWorkORderId("Order # 44");

        // 1) Load ODT file by filling Velocity template engine and cache it to the registry
        IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Velocity);

        // 2) Create context Java model
        IContext ctx = report.createContext();
        ctx.put("job_info", jobInfo);

        // 3) Generate report by merging Java model with the ODT
        File dir = new File(Environment.getExternalStorageDirectory()+"/tests/reports");
        dir.mkdirs();
        File file = new File(dir,"/test_report_doc_out.odt");
        file.createNewFile();
        OutputStream out = new FileOutputStream(file);
        report.process(ctx, out);
angelozerr commented 4 years ago

It's not really a problem with XDocReport with sax. hav you checked org.xmlpull.v1.sax2.Driver is in your classpath in Android context?

d-j-kendall commented 4 years ago

Yes, I am guessing if it wasn't this would throw a ClassNotFoundException

 Class obj = Class.forName("org.xmlpull.v1.sax2.Driver", true, this.getClass().getClassLoader());