大きなファイルを読み込んでみたくて、前回のサンプルをベースに、むりやりファイルを読み込む処理を付け足して、大きめのサイズ(48MB 強)の HTML のテーブルを読み込ませてみました。
例に示した読み込むファイルの拡張子は、.xls になっていますが、中身は HTML です。ただし、読み込む形式が判っているので、汎用のパーサーを用いずに、一行ずつ読み込んで専用の処理をしています。このファイルはあるシステムが吐き出すログなのですが、詳細な説明は割愛します。
List: NatTableSample002.java
/******************************************************************************* * Copyright (c) 2012 Original authors and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Original authors and others - initial API and implementation ******************************************************************************/ // modified by Fuhito Suguri, 9-Sep-2014 package nattablesample; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.jface.window.ApplicationWindow; import org.eclipse.nebula.widgets.nattable.NatTable; import org.eclipse.nebula.widgets.nattable.data.IDataProvider; import org.eclipse.nebula.widgets.nattable.data.ListDataProvider; import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor; import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider; import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider; import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider; import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer; import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer; import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer; import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer; import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer; import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform; import org.eclipse.nebula.widgets.nattable.layer.DataLayer; import org.eclipse.nebula.widgets.nattable.reorder.ColumnReorderLayer; import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer; import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; public class NatTableSample002 extends ApplicationWindow { private IDataProvider bodyDataProvider; private BodyLayerStack bodyLayer; private String[] propertyNames; private Map<String, String> propertyToLabels; public NatTableSample002() { super(null); } @Override protected Control createContents(Composite parent) { parent.setSize(400, 200); FillLayout layout = new FillLayout(SWT.HORIZONTAL | SWT.VERTICAL); // Body Layer bodyDataProvider = setupBodyDataProvider(); bodyLayer = new BodyLayerStack(bodyDataProvider); // Column Layer DefaultColumnHeaderDataProvider colHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabels); ColumnHeaderLayerStack columnHeaderLayer = new ColumnHeaderLayerStack(colHeaderDataProvider); // Row Layer DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider); RowHeaderLayerStack rowHeaderLayer = new RowHeaderLayerStack(rowHeaderDataProvider); // Corner Layer DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(colHeaderDataProvider, rowHeaderDataProvider); CornerLayer cornerLayer = new CornerLayer(new DataLayer(cornerDataProvider), rowHeaderLayer, columnHeaderLayer); // Grid Layer GridLayer gridLayer = new GridLayer(bodyLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer); NatTable natTable = new NatTable(parent, gridLayer); natTable.setLayout(layout); return natTable; } // setupBodyDataProvider private IDataProvider setupBodyDataProvider() { String fileName = "/home/bitwalk/ドキュメント/myExcel.xls"; propertyToLabels = new HashMap<String, String>(); propertyToLabels.put("lictype", "ライセンス タイプ"); propertyToLabels.put("monthdate", "月の日"); propertyToLabels.put("userid", "ユーザーID"); propertyToLabels.put("site", "サイト"); propertyToLabels.put("available", "アベイラビリティ"); propertyToLabels.put("percentused", "パーセント使用"); propertyToLabels.put("start", "開始"); propertyToLabels.put("end", "終了"); propertyNames = new String[] { "lictype", "monthdate", "userid", "site", "available", "percentused", "start", "end" }; List<LicData> licUsage = new ArrayList<LicData>(); try { File file = new File(fileName); if (checkBeforeReadfile(file)) { BufferedReader br = new BufferedReader(new FileReader(file)); String str; String[] elem = new String[8]; int counter = 0; while ((str = br.readLine()) != null) { String line = str.trim(); if (line.length() == 0) { continue; } if (line.equals("<tr>")) { counter = 0; continue; } if (line.equals("</tr>")) { licUsage.add(new LicData(elem[0], elem[1], elem[2], elem[3], elem[4], elem[5], elem[6], elem[7])); continue; } if (line.startsWith("<td>")) { int lLength = line.length(); elem[counter] = new String(line.substring(4, lLength - 5)); counter++; } } br.close(); } else { System.out.println("Can not find or can not open the file!"); } } catch (FileNotFoundException e) { System.out.println(e); } catch (IOException e) { System.out.println(e); } return new ListDataProvider<LicData>(licUsage, new ReflectiveColumnPropertyAccessor<LicData>(propertyNames)); } private static boolean checkBeforeReadfile(File file) { if (file.exists()) { if (file.isFile() && file.canRead()) { return true; } } return false; } // row structure of license usage data public class LicData { private String lictype; private String monthdate; private String userid; private String site; private String available; private String percentused; private String start; private String end; public LicData(String lictype, String monthdate, String userid, String site, String available, String percentused, String start, String end) { this.lictype = lictype; this.monthdate = monthdate; this.userid = userid; this.site = site; this.available = available; this.percentused = percentused; this.start = start; this.end = end; } public String getLictype() { return lictype; } public String getMonthdate() { return monthdate; } public String getUserid() { return userid; } public String getSite() { return site; } public String getAvailable() { return available; } public String getPercentused() { return percentused; } public String getStart() { return start; } public String getEnd() { return end; } } // class BodyLayerStack public class BodyLayerStack extends AbstractLayerTransform { private SelectionLayer selectionLayer; public BodyLayerStack(IDataProvider dataProvider) { DataLayer bodyDataLayer = new DataLayer(dataProvider); ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(bodyDataLayer); ColumnHideShowLayer columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer); selectionLayer = new SelectionLayer(columnHideShowLayer); ViewportLayer viewportLayer = new ViewportLayer(selectionLayer); setUnderlyingLayer(viewportLayer); } public SelectionLayer getSelectionLayer() { return selectionLayer; } } // class ColumnHeaderLayerStack public class ColumnHeaderLayerStack extends AbstractLayerTransform { public ColumnHeaderLayerStack(IDataProvider dataProvider) { DataLayer dataLayer = new DataLayer(dataProvider); ColumnHeaderLayer colHeaderLayer = new ColumnHeaderLayer(dataLayer, bodyLayer, bodyLayer.getSelectionLayer()); setUnderlyingLayer(colHeaderLayer); } } // class RowHeaderLayerStack public class RowHeaderLayerStack extends AbstractLayerTransform { public RowHeaderLayerStack(IDataProvider dataProvider) { DataLayer dataLayer = new DataLayer(dataProvider, 100, 20); RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(dataLayer, bodyLayer, bodyLayer.getSelectionLayer()); setUnderlyingLayer(rowHeaderLayer); } } public static void main(String[] args) { NatTableSample002 w = new NatTableSample002(); w.setBlockOnOpen(true); w.open(); Display.getCurrent().dispose(); } }
実行例
79,446 行というのは、Excel で扱えない行数では決してありませんが、こんなに簡単に読み込めるんだということでオドロキです。もっとも読み込み速度が速いのは、単純にファイルの読み込み処理を特化しているせいなのでしょう。
定型のデータを読み込ませる場合は、このようなやり方で良いのですが、汎用目的に読み込むためにどうするのか、調べる必要があります。
0 件のコメント:
コメントを投稿