LibreOffice、jodconverter、TinyMCEに基づいた視覚的なWebベースのドキュメントエディターを作成します。

オフィスの仕様が大好きです! テンプレートを使用してExcelドキュメントを生成することに関する以前の記事を書いてから、多くの時間が経過し、タスクが多少変更されました。 新しいタスクは次のように設定されました。完成したExcelまたはWordドキュメントから、Webインターフェイスを介してテンプレートを作成します。 形成の過程で、テンプレートの必要な値を置き換え、テンプレートの一部を削除および/または「クローン」します。 形成後、ユーザーはドキュメントをブラウザで視覚的に編集できるようになります。 完成したドキュメントはサーバーに保存し、拡張子(* .doc / *。Xls)とPDFの両方でユーザーがダウンロードできるようにする必要があります。 同時に、ダウンロードしたファイルのレイアウトは、最初にロードされたテンプレートと同じである必要があります(マージンと印刷領域の歪みなし)。

さて、問題があります-私たちはそれを解決します!





1.実績のあるツール

まず、ダウンロードしたファイルをdoc、docx、xls、xlsxからhtml、またはその逆から、レイアウトを乱すことなく蒸留する方法を決定する必要があります。



Apache POI:私たちが成功裏に使用した素晴らしいツールですが、既存のドキュメントからHTMLマークアップを生成する方法を知りません。

DocX4J:これには長い話があります。 彼女は、何度も書いてきたあらゆる楽しいことをする方法を知っています。 そして当初、この特定のライブラリを使用したかったのです。

DocX4Jの欠点:docxとxlsxでのみ作業できます。 しかし、それはそれほど怖くない。 HTMLをdocxまたはxlsxに戻すときに問題が始まります。 ドキュメントのすべてのスタイルが使用され、フォントは一般的に任意に書き込まれます。 開発者に頼りました。 彼は、そのような問題があり、有料版-docx4j-web-editorで部分的に解決されていると言いました。 しかし、有料版にはバグもあることが判明しました。 Kotsovの終わりには、このライブラリも放棄しなければなりませんでした。



解決策は、LibreOfficeを使用することです。 サーバー上で彼にファイルをHTMLに、またはその逆に変換させます。 Webアプリケーションと接続するためだけに残ります。

LibreOfficeを使用するには、小さなライブラリが使用されます-残念ながら、長い間更新されていませんが、 正常に動作します。 TCPソケットを介してLibreOfficeに接続し、変換用のファイルを提供し、変換されたファイルが応答します。 これらはすべて、上記のすべてのJavaライブラリよりもはるかに高速かつ正確に機能します。 さらに、LibreOfficeはそのプロセスで動作し、Webアプリケーションのヒープ内のドキュメントを解析および保存するなどの面倒なタスクからJavaアプリケーションを解放します。



2.ファイルをサーバーにアップロードし、そこからテンプレートを作成します



ただし、jodconverterはサーバー上のファイルシステムで動作します。 したがって、ダウンロードしたファイルをWebアプリケーションから転送し、逆の問題を解決する必要があります-HTMLを目的のファイル形式に変換してユーザーに提供します。



猫の下には、jodconverterのコメント付きの小さなラッパークラスがあります。
Libre.java

package ru.cpro.uchteno.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.logging.Level; import java.util.logging.Logger; import org.artofsolving.jodconverter.OfficeDocumentConverter; import org.artofsolving.jodconverter.office.ExternalOfficeManagerConfiguration; import org.artofsolving.jodconverter.office.OfficeConnectionProtocol; import org.artofsolving.jodconverter.office.OfficeManager; public class Libre {//    public static void doc2html(InputStream is, OutputStream os) {// doc  html try { File inf = File.createTempFile("doc", ".doc"); //   FileOutputStream infos = new FileOutputStream(inf); //    //        int n = 0; byte buff[] = new byte[1024]; while (n >= 0) { n = is.read(buff); if (n > 0) { infos.write(buff, 0, n); } } //  is.close(); infos.close(); //   File onf = File.createTempFile("doc", ".html"); //  jodconverter' ExternalOfficeManagerConfiguration officeConfiguration = new ExternalOfficeManagerConfiguration(); // tcp  officeConfiguration .setConnectionProtocol(OfficeConnectionProtocol.SOCKET); // officeConfiguration.setPortNumber(2002); //   officeManager OfficeManager officeManager = officeConfiguration .buildOfficeManager(); //     officeManager.start(); //  OfficeDocumentConverter converter = new OfficeDocumentConverter( officeManager); //    converter.convert(inf, onf); //  officeManager.stop(); //         FileInputStream outfis = new FileInputStream(onf); n = 0; while (n >= 0) { n = outfis.read(buff); if (n > 0) { os.write(buff, 0, n); } } //  outfis.close(); os.close(); //   inf.delete(); onf.delete(); } catch (IOException ex) { Logger.getLogger(Libre.class.getName()).log(Level.SEVERE, null, ex); } } public static void doc2pdf(InputStream is, OutputStream os) { try { File inf = File.createTempFile("doc", ".doc"); FileOutputStream infos = new FileOutputStream(inf); int n = 0; byte buff[] = new byte[1024]; while (n >= 0) { n = is.read(buff); if (n > 0) { infos.write(buff, 0, n); } } is.close(); infos.close(); File onf = File.createTempFile("doc", ".pdf"); ExternalOfficeManagerConfiguration officeConfiguration = new ExternalOfficeManagerConfiguration(); officeConfiguration .setConnectionProtocol(OfficeConnectionProtocol.SOCKET); officeConfiguration.setPortNumber(2002); OfficeManager officeManager = officeConfiguration .buildOfficeManager(); officeManager.start(); OfficeDocumentConverter converter = new OfficeDocumentConverter( officeManager); converter.convert(inf, onf); officeManager.stop(); FileInputStream outfis = new FileInputStream(onf); n = 0; while (n >= 0) { n = outfis.read(buff); if (n > 0) { os.write(buff, 0, n); } } outfis.close(); os.close(); inf.delete(); onf.delete(); } catch (IOException ex) { Logger.getLogger(Libre.class.getName()).log(Level.SEVERE, null, ex); } } public static void html2doc(InputStream is, OutputStream os) { try { File inf = File.createTempFile("doc", ".html"); FileOutputStream infos = new FileOutputStream(inf); int n = 0; byte buff[] = new byte[1024]; while (n >= 0) { n = is.read(buff); if (n > 0) { infos.write(buff, 0, n); } } is.close(); infos.close(); File onf = File.createTempFile("doc", ".doc"); ExternalOfficeManagerConfiguration officeConfiguration = new ExternalOfficeManagerConfiguration(); officeConfiguration .setConnectionProtocol(OfficeConnectionProtocol.SOCKET); officeConfiguration.setPortNumber(2002); OfficeManager officeManager = officeConfiguration .buildOfficeManager(); officeManager.start(); OfficeDocumentConverter converter = new OfficeDocumentConverter( officeManager); converter.convert(inf, onf); officeManager.stop(); FileInputStream outfis = new FileInputStream(onf); n = 0; while (n >= 0) { n = outfis.read(buff); if (n > 0) { os.write(buff, 0, n); } } outfis.close(); os.close(); inf.delete(); onf.delete(); } catch (IOException ex) { Logger.getLogger(Libre.class.getName()).log(Level.SEVERE, null, ex); } } public static void html2docx(InputStream is, OutputStream os) { try { File inf = File.createTempFile("doc", ".html"); FileOutputStream infos = new FileOutputStream(inf); int n = 0; byte buff[] = new byte[1024]; while (n >= 0) { n = is.read(buff); if (n > 0) { infos.write(buff, 0, n); } } is.close(); infos.close(); File onf = File.createTempFile("doc", ".docx"); ExternalOfficeManagerConfiguration officeConfiguration = new ExternalOfficeManagerConfiguration(); officeConfiguration .setConnectionProtocol(OfficeConnectionProtocol.SOCKET); officeConfiguration.setPortNumber(2002); OfficeManager officeManager = officeConfiguration .buildOfficeManager(); officeManager.start(); OfficeDocumentConverter converter = new OfficeDocumentConverter( officeManager); converter.convert(inf, onf); officeManager.stop(); FileInputStream outfis = new FileInputStream(onf); n = 0; while (n >= 0) { n = outfis.read(buff); if (n > 0) { os.write(buff, 0, n); } } outfis.close(); os.close(); inf.delete(); onf.delete(); } catch (IOException ex) { Logger.getLogger(Libre.class.getName()).log(Level.SEVERE, null, ex); } } public static void html2pdf(InputStream is, OutputStream os) { try { File inf = File.createTempFile("doc", ".html"); FileOutputStream infos = new FileOutputStream(inf); int n = 0; byte buff[] = new byte[1024]; while (n >= 0) { n = is.read(buff); if (n > 0) { infos.write(buff, 0, n); } } is.close(); infos.close(); File onf = File.createTempFile("doc", ".pdf"); ExternalOfficeManagerConfiguration officeConfiguration = new ExternalOfficeManagerConfiguration(); officeConfiguration .setConnectionProtocol(OfficeConnectionProtocol.SOCKET); officeConfiguration.setPortNumber(2002); OfficeManager officeManager = officeConfiguration .buildOfficeManager(); officeManager.start(); OfficeDocumentConverter converter = new OfficeDocumentConverter( officeManager); converter.convert(inf, onf); officeManager.stop(); FileInputStream outfis = new FileInputStream(onf); n = 0; while (n >= 0) { n = outfis.read(buff); if (n > 0) { os.write(buff, 0, n); } } outfis.close(); os.close(); inf.delete(); onf.delete(); } catch (IOException ex) { Logger.getLogger(Libre.class.getName()).log(Level.SEVERE, null, ex); } } }
      
      









3.テンプレートを使用します



HTMLがあれば、必要な操作は速度を使用して非常に簡単に実行できます。 説明に従ってすべてが簡単に行われます



4.ドキュメントの視覚的な編集



ビジュアルエディターには独自の特性があります。ビジュアルエディターはHTMLコードを台無しにします。逆変換すると、ドキュメントのレイアウト全体が認識できないほど歪んでしまいます。 さまざまな編集者による実験の過程で、彼らはTinyMCEが少なくとも何よりもマークアップを巧妙にゆがめ、元に戻すときの最終結果に実質的に影響を与えないという結論に達しました。



その結果、試行錯誤の方法で最適なエディター構成を選択しました。



 tinymce.init({ selector: "textarea", theme: "modern", fullpage_default_doctype: "<!DOCTYPE xhtml>", plugins: [ "advlist autolink lists link image charmap print preview hr anchor pagebreak", "searchreplace wordcount visualblocks visualchars code fullscreen", "insertdatetime media nonbreaking save table contextmenu directionality", "emoticons template paste textcolor fullpage" ], toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image", toolbar2: "print preview media | forecolor backcolor emoticons", image_advtab: true });
      
      







毎回、DOMのエディターの内容をリセットするには、 tinyMCE.triggerSave();



を行うことを忘れないでくださいtinyMCE.triggerSave();







5.完成したドキュメントをダウンロードする



これらの目的のために、再びLibre.java



ライブラリを使用します。



htmlからdocへの変換html2doc()





HTMLをdocxに変換html2docx()





htmlからpdfへの変換html2pdf()







実際、それがすべてです。 この記事が誰かを助け、タンバリンとのダンスに費やされる時間を減らすことができれば嬉しいです!



作成者: akaiserボイラー5



All Articles