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.19k stars 369 forks source link

NoSuchMethodError while trying to convert odt to pdf #622

Open MarekChr opened 12 months ago

MarekChr commented 12 months ago

Code:

package main;

import fr.opensagres.odfdom.converter.pdf.PdfConverter;
import org.odftoolkit.odfdom.doc.OdfDocument;

import java.io.FileOutputStream;
import java.io.InputStream;

public class Main {
    public static void main(final String[] args) throws Exception {
        try (final InputStream input = Main.class.getResourceAsStream("stats.odt")) {
            final var doc = OdfDocument.loadDocument(input);
            try (final var output = new FileOutputStream("converted.pdf")) {
                PdfConverter.getInstance().convert(doc, output, null);
            }
        }
    }
}

Exception:

Exception in thread "main" java.lang.NoSuchMethodError: 'org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeAutomaticStyles org.odftoolkit.odfdom.dom.OdfStylesDom.getAutomaticStyles()'
    at fr.opensagres.odfdom.converter.pdf.PdfConverter.processStyles(PdfConverter.java:112)
    at fr.opensagres.odfdom.converter.pdf.PdfConverter.doConvert(PdfConverter.java:62)
    at fr.opensagres.odfdom.converter.pdf.PdfConverter.doConvert(PdfConverter.java:44)
    at fr.opensagres.odfdom.converter.core.AbstractODFConverter.convert(AbstractODFConverter.java:42)

It occurs in processStyles method in PdfConverter class at line 112: stylesDom.getAutomaticStyles().accept( styleEngine );

Dependencies:

<dependencies>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>xdocreport</artifactId>
            <version>2.0.4</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>org.odftoolkit.odfdom.converter.pdf</artifactId>
            <version>1.0.6</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.converter.odt.odfdom</artifactId>
            <version>2.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.odftoolkit</groupId>
            <artifactId>odfdom-java</artifactId>
            <version>0.11.0</version>
        </dependency>
    </dependencies>

Am I missing some kind of dependency or it is just not working? .odt file was created with LibreOffice Writer 7.4. Any help appretiated.

Dan-Ilie commented 12 months ago

Today I ran into the same issue. The problem seems using a newer version of odfdom-java. In the wiki it states using version 0.8.7 (while we both went for version 0.11.0)

The thing is, version 0.8.7 has the issue that you can't modify a odt file in the sense of targeting a cell in a table and changing the text there because OdfTableRow getCellCount() is always returning 0, and getCellByIndex() will always throw an error. This issue is fixed in the latest version 0.11.0, but the latest version can't be used with xdocreport in order to convert from odt to pdf.

The solution seems to be ironing out the differences between version 0.8.7 and 0.11.0 for odfdom-java as a dependency for xdocreport.

angelozerr commented 11 months ago

Any contribution are welcome!

mwildam commented 8 months ago

Yes, newer versions require different way of building the document:

        InputStream input = new FileInputStream(new File(pdfInputFileName));
        IXDocReport report = XDocReportRegistry.getRegistry().loadReport(input, TemplateEngineKind.Velocity);
        IContext context = report.createContext();
        DocProps doc = new DocProps(); // Or whatever POJO you use to put your data into
        doc.setDocTitle("My test report");
        ...
        context.put("doc", doc);
        Options options = Options.getFrom(DocumentKind.ODT).to(ConverterTypeTo.PDF);
        OutputStream output = new FileOutputStream(new File(pdfOutputFileName));
        report.convert(context, options, output);
        System.out.println("File written: " + pdfOutputFileName);