Add ability to set PDF export options

Issue #1 new
Anonymous created an issue

When exporting a document to PDF with libreoffice via the menu "File > Export as PDF", there is a panel with several options across multiple tabs:

libreoffice PDF options

I would like to be able to set some of these options via py3o. My immediate need would be to activate the option "Archive PDF/A-1 (ISO 19005-1)", to be able to produce a valid Factur-X invoice with the factur-x lib available from https://github.com/akretion/factur-x : this lib needs a valid PDF/A as input to produce a valid PDF/A-3 as output.

A rapid Google search lead me to this web page with code sample (it is for openoffice.org and not for libreoffice, but I haven't found the libreoffice equivalent yet): https://wiki.openoffice.org/wiki/API/Tutorials/PDF_export

Any advice to implement that ?

Comments (16)

  1. Alexis de Lattre

    I made a first working patch tonight: https://people.via.ecp.fr/~alexis/py3o.renderers.juno-filterdata.diff

    Once this patch is applied, I run "java/py3oconvertor/compile.sh" and then I copy "py3o/renderers/juno/py3oconverter.jar" to the right place.

    The available options PDF export filter options can be found in the libreoffice source code here: https://cgit.freedesktop.org/libreoffice/core/tree/filter/source/pdf/pdfexport.cxx#n438

    Next step: think how we could make these PDF filter options dynamic parameters.

  2. Florent Aide repo owner

    Hi Alexis

    I am really interested in this. I'll try to find some time to help when I get out of the current rush state I'm in. I wanted you to know I really support and appreciate the effort you're putting into this!

  3. Alexis de Lattre

    Florent,

    Thank you for your message. It encourage me to continue to work on this. The next step will be to design how we plan to transmit the PDF filter option through all the chain : Odoo -> py3o.fusion -> py3o.renderserver -> py3o.renderers.juno. I'll start to look into this, and I'll appreciate your feedback when your rush period will be over.

  4. Alexis de Lattre

    I made a first rapid code analysis: this new features involves modifing:

    • the Odoo module report_py3o (where we would define the pdf filter parameters)
    • py3o.fusion
    • py3o.renderclient
    • py3o.renderserver
    • and of course the present project py3o.renderers.juno

    I haven't seen a way to pass additional data through py3o.fusion -> py3o.renderclient -> py3o.renderserver without modifing their code. The modification may not be very complex, but the difficulty is that we would need to make 5 PRs across 5 different projects !

  5. Alexis de Lattre

    OK, I'm getting pretty close:

    • I have added support for PDF Export options in Odoo
    • the PDF options are received by py3o.fusion and given to py3o.renderclient
    • the PDF options are sent to py3o.renderserver
    • the PDF options arrive in py3o.renderers.juno
    • it seems I managed to make them cross the Python/Java barrier (via an Array of ListArray ; I choose Array of ListArray because ListArray is supposed to be able to mix different types)

    But I'm having difficulties setting up the FilterData in convert_document. My problem is that I'm "blind" in the Java code. I added some "System.out.println()" in the code, but I don't see the output of it. I think that if someone tells me how I can make "System.out.println()" work in the Java code of py3o.renderers.juno, then I should be able to make it work and I'll make the 5 pull requests.

  6. Alexis de Lattre

    Still fighting with the Java code... I haven't found any information about the possibility to have Java logs in the output of py3o.renderserver... it may not be possible. But it seems that the java file py3o.renderers.juno/java/py3oconvertor/py3oconverter/Launch.java is designed to start the Java code directly with JVM (without py3o.renderserver), and in this case I should be able to have the logs in the console.

    But I haven't succeeded to start the Java code directly:

    cd py3o.renderers.juno/java/py3oconvertor
    ./compile.sh
    -> no errors ; I get new .class files in the "py3oconverter" subdir
    cd py3oconverter
    java -Djava.class.path=/home/alexis/new_boite/dev/py3o.renderers.juno/py3o/renderers/juno/py3oconverter.jar:/usr/share/java/juh.jar:/usr/share/java/jurt.jar:/usr/share/java/ridl.jar:/usr/share/java/unoloader.jar:/usr/share/java/java_uno.jar:/usr/lib/libreoffice/program/classes/unoil.jar Launch
    Error: Could not find or load main class Launch
    

    I'm stuck with this. Any help would be greatly appreciated.

  7. Alexis de Lattre

    Raphaël Valyi has kindly helped me on my Java issues, and I'm proud to annonce that I am able to generate PDF documents via py3o with PDF options configured in Odoo! The immediate consequence is that I can now generate: - watermarked PDF - PDF forms - PDF/A documents (needed for Factur-X) - etc... so it opens many new possibilities ! It should even be possible to generate signed PDF because libreoffice supports this (but I haven't tested it yet via py3o). The current implementation is quite dirty, in particular the transmission of pdf options from python to Java : as I had too many problems with Arrays with jpype, I concatened all PDF options in a big string with field separators and variable types in the python code, send the string from python to Java and parse the string in Java... this is quite dirty, so I'll try to clean it up and work with JSON, as suggested by Raphaël... I'll try that in the next days. I'll publish as soon as it is reasonably clean :)

  8. Alexis de Lattre

    I continued the work on this tonight. I have now implemented all the PDF export options in Odoo and I'm pretty close to publishing the odoo module, but there is still some improvements/cleanup to be done.

  9. Alexis de Lattre

    I'm working on re-writing the Java code of my work, because it was very ugly. As Raphaël suggested, I'll try to use Json to cross the Python/Java border and then use a JSON parser in Java. But there is no native JSON parser in java, so I have to choose one, which will imply updating the classpath to get it. I plan to use google-gson, which seems very standard. Any objection ? I'm stull unsure about how we are supposed to provide the .jar for this lib...

  10. Alexis de Lattre

    The Odoo PR is available here: https://github.com/OCA/reporting-engine/pull/211

    The PR py3o.renderers.juno probably still needs improvement:

    1. maybe we could try to send only one additionnal argument between Python and Java instead of 2 (pdf_options_json and pdf_options_types_json): we could try to integrate all the information in a single JSON
    2. fix Java compile warnings
    py3o.renderers.juno/java/py3oconvertor % ./compile.sh
    py3oconverter/Convertor.java:136: warning: [unchecked] unchecked conversion
            Map<String, String> pdf_options_map = new Gson().fromJson(pdf_options, Map.class);
                                                                     ^
      required: Map<String,String>
      found:    Map
    py3oconverter/Convertor.java:137: warning: [unchecked] unchecked conversion
            Map<String, String> pdf_options_types_map = new Gson().fromJson(pdf_options_types, Map.class);
                                                                           ^
      required: Map<String,String>
      found:    Map
    2 warnings
    

    Help is welcomed.

  11. Houzéfa Abbasbhay

    Gj, looking great!

    The only thing that looks strange to me is having to JSON-serialize pdf_options when transmitting it from py3o.renderclient to py3o.renderserver; I'd have thought the existing protocol these 2 components are using would allow a dict to flow in as is.

  12. Alexis de Lattre

    It seems we can avoid dict to json conversion in renderclient (I guess pyf.station.client is doing it for us when it gets a dict as argument), so I updated my PR on renderclient. But we still need to convert from str to json in renderserver, so I didn't change the code there.

  13. Alexis de Lattre

    My previous comment was wrong... I guess I tested it too fast and forgot proper deployment of the new version of py3o.renderclient after change. So I reverted my commit on py3o.renderclient. If you think you can avoid dict to json conversion in py3o.renderclient, please provide a patch and I'll review it.

  14. Log in to comment