Java8読み取り許可およびExcelは、より簡単かつ効率的になる書き込み

ApacheのPOI

事業開発では、我々は多くの場合、Excelのインポートおよびエクスポートに遭遇し、ApacheのPOIは Java開発者の共通APIです。[ Poi.apache.org/components / ... ]

GridExcel

関数型プログラミングとPOI EventModelに基づいて、単純にExcelを読み書き用ユニバーサルソリューション

GridExcel一般的な解決策は単純な読み取りに基づいており、エクセルJava8 POI EventModel関数型プログラミングと実装のために書き込みされています。

  • データの量が読んで、非常に大きなExcelを書くとき、POI EventModelに基づいて、縮小メモリフットプリントとOOM頻繁FullGCを避けます
  • 関数型プログラミング、サポートや複雑な状況の処理に関連する他のオブジェクト、低コストの学習に基づいて、
  • APIをストリーミングサポート、コーディングや、よりシンプルで直感的なことが理解されます

イベントモデル

何がEventModelはPOIのFAQ(よくある質問)[ poi.apache.org/help/faq.ht ... ]公式の説明で与えられ:

SSのeventmodelパッケージはメモリにスプレッドシート全体をロードせずにExcelファイルを読み込むためのAPIです。これは、ユーザーの側でより多くの知識を必要としませんが、十倍以上にすることにより、メモリの消費量を削減します。これは、SAXとの組み合わせでAWTイベントモデルに基づいています。あなたは読み取り専用アクセスが必要な場合は、これはそれを行うための最善の方法です。

SSのeventmodelパッケージは、メモリAPIに全体のExcelスプレッドシートをロードせずに、ファイルを読み取るために使用されます。これは、より多くの知識を持っているユーザーを必要としませんが、十倍以上のメモリ消費量を削減します。これは、AWT(なAbstract Window Toolkitの)イベントモデルのSAX結合に基づいています。あなたは読み取り専用アクセスが必要な場合は、これが最良の方法です。

関数型プログラミング

それは関数型プログラミングに来るとき、あなたは言及しなければならないラムダ式を Java8ラムダは理解していないか、深遠を理解していない場合、あなたはOracleの公式サイト、[与えられたこの記事を見ることができ、www.oracle.com/technetwork ... ]、個人Java8ラムダは、これは、高度な記事へのエントリから最高の一つだと思います。

前記目的関数は、プログラミングを達成することである代码块传递、すなわち、パラメータとしてメソッドとの間を通過する方法。いくつかのソリューションを新興、Java言語の開発と、この目的のために:

  1. ジャワ1.0、抽象ウィンドウツールキット(AWT)を達成するEventModelが、不器用なと非現実的に使用
  2. 「リスナー」のシリーズを提案したJava 1.1、
  3. 後で使用内部类して匿名内部类達成するために、ほとんどの場合、彼らは単にイベント処理として使用されています。
  4. 後の世代は、より多くの場所を見つけるだろう码块作为对象(実際のデータ)を便利で必要なだけではありませんが、Javaのプログラミング機能はまだそれが成長する必要があり、非常に不器用です。
  5. Javaの1.7までは、Javaが動的に(硬化もはや仮想マシンのバイトコード呼び出し命令だけに頼ることはできません)対象のメカニズムを決定するための新規な方法を提供するために、パッケージをjava.lang.invoke導入、MethodHandle、シミュレートされた単語を言及この方法は、中にC / C ++と同様、バイトコード・ポインタをコールポインタ関数(関数ポインタ)5物品法に導入されたバイトコード命令を呼び出しinvokedynamicの
  6. ジャワ1.8提案に基づいて、Java(登録商標)1.7バイトコード命令までinvokedynamicの、ラムダは、パラメータ間の伝送方式の関数として、技術を実現し、Javaはより良い機能的なプログラミングをサポートし始めます。
  7. 反射はありませんずっと前にそれを達成することができますか?リフレクションAPIのヘビー級、性能が低いです。

注:5,6,7は、第2版、8.3.3動的型付け言語のサポート「Java仮想マシンの深い理解」を参照します。


で、多くの場合、2つの問題に直面POIの使用では、ほとんどのAPIユーザー、GridExcelの問題解決の努力。

質問1のみを使用して、簡単なインポートおよびエクスポート機能が、それぞれ異なるデータオブジェクト構造サービス、あなたは再書き込みアプローチ、トラブルの多くする必要があります!

ソリューション

処理ロジックは、Excelツールにカプセル化され、抽出されました。

包装条件

ほとんどのJava APIと同様に、POIは、そのようなので、上式(式)、条件付き書式(条件付き書式)、ズーム(ズーム)として、高度な機能の治療にもっと焦点を置きます。単にデータのインポートおよびエクスポート機能のAPIのユーザーを行うため、めったにユーザーがPOIのAPIシンプルなパッケージを使用することができますこれらの高度な機能を使用しません。

パッケージ

読書が書き込まれているかどうか、我々はすべてのExcelの列(列)に対処する必要がJavaデータに関連付けられたマッピングは、そのようなツールに渡されたパラメータ(地図HashMapのかのLinkedHashMapオブジェクト)との間のマッピングなどのフィールド(フィールド)、オブジェクト。

それは理解されるであろうカラムの、それが順序付け数字または文字であってもよく、他の文字列は、列が意味のデータを示し、最初のラインとして使用することができます。

フィールドの場合、それは次のように、複雑な状況を扱う互換性がある必要があります:

  • 例外が発生したときに、クエリのフィールドを
  • フィールドまたはセルがnullの場合
  • これは、列の値関連するオブジェクト、または関連するコレクションであっても特定のフィールドの値に対応してもよいです
  • 値フィールド、または細胞特別な処理を必要とする、例えばvalue == true?完成:失败;
反射

最初に私は思ったが、また、使用しているほとんどのパッケージ化方法があるリフレクションAPIの上から、関数型プログラミング、我々は反射ヘビー級は、複雑な状況の同時処理が十分ではありませんサポート、コードのパフォーマンスが低下することを学んだの章。

ノートの反射+

このように私たちはより良い複雑な状況をサポートしていますが、まだ侵襲引き起こす可能性があり、アノテーションデータオブジェクトコード、および他のユーザーのツールパッケージは間違いなく学習のコストが増加する一方、低パフォーマンスを反映することができます。

匿名内部クラス

この方法でも良いサポート複雑な状況であってもよいが、匿名の内部クラスの構文を使用することは明らかにあまりにもごちゃ混ぜ、(基本的な概念を表現するために必要なコードの、あまりにも多くの行を意味する)「縦の問題」に苦しんでいます。パフォーマンスに関しては、それが必要ではない、それを迅速にダイレクト転送機能として。

関数インタフェース(ラムダ)

このアプローチは、メソッドの第5条を呼び出すためにバイトコード命令に基づいてinvokedynamicのは、直接機能ブロックを転送し、簡単な構造で記述された良好な支持複雑な場合、より高い性能、コードをよりコンパクトで実施するが、ゼロのデータ・オブジェクト・コード侵攻。

2. Excelの問題のインポートや、その結果、大量のデータをエクスポートし内存溢出、または频繁的Full GC、解決策は何ですか?

ソリューション

  • 読書エクセル - eventmodel
  • 写エクセル - streaming.SXSSFWorkbook

原則

POIの使用は全く見知らぬ人はいけません、次の二つの概念のために、私たちにとって非常に一般的です。

  • HSSFWorkbook(処理97(-2007)が.XLSです)
  • XSSFWorkbook(処理2007 OOXML(の.xlsx))

しかしためeventmodelstreaming.SXSSFWorkbookと非常に少ない接触、彼らはPOIのメモリフットプリントの問題解決するために設計されて低レベルAPI読み、Excelに非常に大量のデータを使用して書くことができます(低レベルAPIを)、および避けます内存溢出频繁的Full GC[ Poi.apache.org/components / ...

  • eventmodelするユーザー、Excelを読み取るため、Excelの全体がメモリにロードされませんが、可能にするInputStreamへのそれぞれについてのいくつかの情報、読みコールバック関数またはリスナーを破棄して、またはこれらのコンテンツをどのように扱うかが格納されているが、クロスしていますユーザーによる。
  • streaming.SXSSFWorkbookにより、Excelを(パッケージのXSSFWorkbookのみの.xlsxサポートされている)を記述するために使用される、スライディングウインドウが達成され、スライディングウィンドウの存在のみを残して行を超えてメモリ内の行の数は、一時ファイルの行に書き込まれることができ呼び出されたとき、write(OutputStream stream)この方法は、コンテンツを書いたときに、ターゲットへの一時メモリから直接書き込むのOutputStreamSXSSFWorkbookの使用は、いくつかの制限があります。
    • 行の数は限ら時点でアクセス可能です。
    • Sheet.clone()がサポートされていません。
    • 式の評価はサポートされていません。

ソリューション

  • github.com/liuhuagui/g ...サポートストリーミングAPI、環境Java1.8以上、学習コストベースのJavaプログラミング機能(ラムダ):ラムダ

実際にPOIの公式ウェブサイトは、ユーザーに例を与えているが、より便利に使用するように、これらのツールは、単に、達成するために、独自のパッケージを実行します。


速いです

<dependency>
    <groupId>com.github.liuhuagui</groupId>
    <artifactId>gridexcel</artifactId>
    <version>2.2</version>
</dependency>
复制代码

GridExcel.java

GridExcel.javaは、いくつかの静的メソッドを提供し、直接使用することができ、式試験コード(設けられたテストデータおよびテスト・ファイル)の特定の実施形態を参照することができます。

ストリーミングAPI

/**
  * 业务逻辑处理方式三选一:
  * 1.启用windowListener,并将业务逻辑放在该函数中。
  * 2.不启用windowListener,使用get()方法取回全部数据集合,做后续处理。
  * 3.readFunction函数,直接放在函数中处理 或 使用final or effective final的局部变量存放这写数据,做后续处理。
  * 注意:使用EventModel时readFunction函数的输入为每行的cell值集合List<String>。
  * @throws Exception
  */
 @Test
 public void readXlsxByEventModel() throws Exception {
     InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("2007.xlsx");
     GridExcel.readByEventModel(resourceAsStream,TradeOrder.class,ExcelType.XLSX)
             .window(2,ts -> System.out.println(JSON.toJSONString(ts)))//推荐在这里执行自己的业务逻辑
             .process(cs ->{
                 TradeOrder tradeOrder = new TradeOrder();
                 tradeOrder.setTradeOrderId(Long.valueOf(cs.get(0)));
                 Consultant consultant = new  Consultant();
                 consultant.setConsultantName(cs.get(3));
                 tradeOrder.setConsultant(consultant);
                 tradeOrder.setPaymentRatio(cs.get(16));
                 return tradeOrder;
             },1);
 }
 /**
  * 使用Streaming UserModel写出数据到Excel
  * @throws Exception
  */
 @Test
 public void writeExcelByStreaming() throws Exception {
     GridExcel.writeByStreaming(TradeOrder.class)
             .head(writeFunctionMap())//对象字段到Excel列的映射
             .createSheet()
             .process(MockData.data())//模拟数据。在这里设置业务数据集合。
             .write(FileUtils.openOutputStream(new File("/excel/test.xlsx")));
 }
复制代码

ReadExcel

ReadExcelByUserModel

Excelファイルを読むためにユーザモデルを使用してください。userModel -

  • 欠点:メモリの消費量は、すべての情報がメモリにロードされ、その後、処理さ秀でるます。
  • 長所:既存のAPI、使って理解しやすいです。
  • シーンを使用してください:Excelで処理できるデータ量が少ないです。
ReadExcelByEventModel

Excelファイルを読み取るためにイベントモデルを使用してください。eventModel -

  • 欠点:なし既製のAPI、使って上級プログラマのためのより複雑な理解は、(GridExcelは目標の一つは、単純なEventModelを利用することです)
  • 長所:非常に小さなメモリフットプリントではなく、冒頭には、メモリにすべてのコンテンツをロードされますが、処理の主な内容は、(保管、使用、廃棄する)利用者に引き渡され、ユーザーが処理するためにリスナー関数をカスタマイズすることができますこれらのコンテンツ。
  • 使用シナリオ:データエクセル、OOMを大量に処理し、頻繁にFullGCを回避することができます

WriteExcel

WriteExcelByUserModel

Excelファイルの書き込みにユーザモデルを使用してください。userModel -

  • 欠点:スプレッドシートオブジェクトがメモリ内に保持を通して生成されるので、ヒープによる書き込みエクセルのサイズ(ヒープ領域)サイズ制限。
  • 長所:使用して、理解しやすいです。
  • 使用シナリオ:あなたはエクセルの少量のデータを書き込むことができます。
WriteExcelByStreaming

非常に大規模なExcelファイルを書き込むためにXSSFのAPIと互換性のあるストリーミング拡張機能を使用してください。ストリーミングuserModel--

  • 短所
    • のみXSSFをサポートしています。
    • Sheet.clone()がサポートされていません。
    • 式の評価はサポートされていません。
    • 行の数は限ら時点でアクセス可能です。
  • 長所:スライディングウィンドウ、内容指定された行の唯一の予約メモリのサイズによって達成、過剰は一時ファイルに書き込まれ、大きさは、Excelのヒープ(ヒープ領域)のサイズの上限を書くなくなりました。
  • 使用シナリオ:あなたは非常に大きなExcelを書くことができます。

問題

ツール・プロセスの使用における問題点は、機能は作者の発行を依頼することができます追加または変更することが必要である:github.com/liuhuagui/gを...

  • たとえば、拡張スタイルの最初の行以外のランクを増やしたいです

[email protected]:あなたが質問がある場合は、作者に連絡することができます

おすすめ

転載: juejin.im/post/5da70298518825208707f13f