When Spreadsheet loads an Excel file, the file is converted into Spreadsheet's data model stored in its memory so that it can be easily integrated with other components or database by manipulating the data model.
<?xml version="1.0" encoding="UTF-8"?> <nodom apply="demo.integration.IntegrationController"> <style> .z-charts{ border: solid 1px; } </style> <script content="zk.googleAPIkey='AIzaSyA3qtYKklh4uaqv7QdBuPnI0e_i2j4sSGw';"/> <borderlayout style="background-color:red" width="100%" height="100%"> <center> <spreadsheet id="fluSpreadsheet" src="/WEB-INF/books/swineFlu.xlsx" width="100%" height="100%" maxVisibleRows="60" maxVisibleColumns="15" style="border:1px solid black;" /> </center> <east size="300px"> <charts id="fluChart" type="pie" vflex="1" hflex="1" /> </east> <south size="60%"> <gmaps id="fluMap" width="100%" height="100%" showLargeCtrl="true" style="border:1px solid black;margin-top:5px"/> </south> </borderlayout> </nodom>
package demo.integration; import io.keikai.api.*; import io.keikai.api.model.*; import io.keikai.api.model.CellData.CellType; import io.keikai.ui.Spreadsheet; import io.keikai.ui.event.*; import org.apache.poi.ss.usermodel.ZssContext; import org.zkoss.chart.*; import org.zkoss.chart.model.*; import org.zkoss.gmaps.*; import org.zkoss.gmaps.event.MapMouseEvent; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.*; import org.zkoss.zk.ui.select.SelectorComposer; import org.zkoss.zk.ui.select.annotation.*; import org.zkoss.zul.Messagebox; import java.text.*; public class IntegrationController extends SelectorComposer<Component> { @Wire private Spreadsheet fluSpreadsheet; @Wire private Gmaps fluMap; @Wire private Charts fluChart; private Sheet sheet; private Gmarker[] gmarkerArray; private final static int NUMBER_OF_GMARKER_ROW = 42; private int row, col; private String prevCellValue; private NumberFormat format; static private String[] COLORS = {"#5377f9","#393e46", "#1eb25c","#ff8b1f", "#b537ff", "#ff3449", "#ffc431","#ff1702", "#74D80B"}; public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); gmarkerArray = new Gmarker[NUMBER_OF_GMARKER_ROW]; sheet = fluSpreadsheet.getSelectedSheet(); Ranges.range(sheet).setFreezePanel(2, 1); format = NumberFormat.getInstance(ZssContext.getCurrent().getLocale()); initChart(); updateChart(); initMap(); } /** * Clicking column B,C doesn't open the corresponding gmarker since opening gmarker will grab the focus which interferes editing cells. * @param event */ @Listen("onCellClick = #fluSpreadsheet") public void openGmarker(CellMouseEvent event) { if (fluMap == null || sheet == null) return; Sheet sheet = event.getSheet(); row = event.getRow(); col = event.getColumn(); prevCellValue = Ranges.range(sheet, row, col).getCellEditText(); if ((row < 2 || row > 41)// the header row || col == 1 || col == 2) return; double lat = parseDouble(Ranges.range(sheet, row, 4).getCellEditText()); double lng = parseDouble(Ranges.range(sheet, row, 5).getCellEditText()); fluMap.setLat(lat); fluMap.setLng(lng); for (Gmarker gmarker : gmarkerArray) { if (gmarker != null && gmarker.isOpen()) gmarker.setOpen(false); } gmarkerArray[row].setOpen(true); Events.echoEvent("onOpenGmarker", fluMap, row); } @Listen("onOpenGmarker = #fluMap") public void openGmarker(Event event){ //because opening gmarker will grab the focus, focus back to spreadsheet to avoid clicking twice fluSpreadsheet.focus(); } @Listen("onEditboxEditing = #fluSpreadsheet") public void onEditboxEditingEvent(EditboxEditingEvent event) throws ParseException { if (sheet == null || fluMap == null) return; String str = (String) event.getEditingValue(); if (col != 1 && col != 2) { setCellEditText(sheet, row, col, str); } if (row > 0 && row < NUMBER_OF_GMARKER_ROW) { updateRow(row, false); } } @Listen("onStopEditing = #fluSpreadsheet") public void onStopEditingEvent(StopEditingEvent event) throws ParseException { if (sheet == null || fluChart == null) return; event.cancel();// set data manually; row = event.getRow(); col = event.getColumn(); String str = (String) event.getEditingValue(); if (col == 1 || col == 2) { Double val = null; try { val = format.parse(str).doubleValue(); setCellEditText(sheet, row, col, str); } catch (ParseException e) { final Integer rowIdx = Integer.valueOf(row); final Integer colIdx = Integer.valueOf(col); final String prevValue = prevCellValue; Messagebox.show("Cell value has to be number format", "Error", Messagebox.OK, Messagebox.EXCLAMATION, new SerializableEventListener<Event>() { private static final long serialVersionUID = 846217931006240721L; public void onEvent(Event event) throws Exception { setCellEditText(sheet, rowIdx, colIdx, prevValue); } }); return; } } else { setCellEditText(sheet, row, col, str); } if (row != 0) {// the header row updateRow(row, true); } if (col == 1) { updateChart(); } } @Listen("onMapClick = #fluMap") public void selectMarker(MapMouseEvent event) { Gmarker marker = event.getGmarker(); if (marker != null) { for (Gmarker gmarker : gmarkerArray) { if (gmarker != null){ if (marker == gmarker) { gmarker.setOpen(!marker.isOpen()); } else if (gmarker.isOpen()) { gmarker.setOpen(false); } } } } } private void initMap() { for (int row = 2; row < NUMBER_OF_GMARKER_ROW; row++) { String state = Ranges.range(sheet, row, 0).getCellEditText(); // String division = sheet.getCell(row, 1).getCellEditText(); int numOfCase = parseInt(Ranges.range(sheet, row, 1) .getCellEditText()); int numOfDeath = parseInt(Ranges.range(sheet, row, 2) .getCellEditText()); String description = Ranges.range(sheet, row, 3).getCellEditText(); double lat = parseDouble(Ranges.range(sheet, row, 4) .getCellEditText()); double lng = parseDouble(Ranges.range(sheet, row, 5) .getCellEditText()); String content = "<span style=\"color:#346b93;font-weight:bold\">" + state + "</span><br/><span style=\"color:red\">" + numOfCase + "</span> cases<br/><span style=\"color:red\">" + numOfDeath + "</span> death<div style=\"background-color:#E8F5Cf;padding:2px\">" + description + "</div>"; Gmarker gmarker = new Gmarker(); gmarkerArray[row] = gmarker; gmarker.setLat(lat); gmarker.setLng(lng); gmarker.setContent(content); fluMap.appendChild(gmarker); if (row == 2) { fluMap.setLat(lat); fluMap.setLng(lng); gmarkerArray[row].setOpen(true); } fluMap.setZoom(5); } } private void initChart() { fluChart.setTitle(""); fluChart.getExporting().setEnabled(false); fluChart.getPlotOptions().getPie().getDataLabels().setEnabled(false); fluChart.getPlotOptions().getPie().setShowInLegend(true); fluChart.setModel(new DefaultPieModel()); } private void updateChart() { ((PieModel) fluChart.getModel()).clear(); Series series = fluChart.getSeries(); for (int row = 45; row < 54; row++) { String name = Ranges.range(sheet, row, 0).getCellData().isBlank() ? "" : Ranges.range(sheet, row, 0).getCellEditText(); CellData cellData = Ranges.range(sheet, row, 1).getCellData(); Double value; if (cellData.getResultType() == CellType.NUMERIC) { value = (Double) cellData.getValue(); } else { value = 0D; } Point point = new Point(name, value); point.setColor(COLORS[(row-45) % COLORS.length]); series.addPoint(point); } } private void updateRow(int row, boolean evalValue) throws ParseException { if (fluMap == null || sheet == null || Ranges.range(sheet, row, 3).getCellData().isBlank()) return; String state = Ranges.range(sheet, row, 0).getCellEditText(); int numOfCase = parseInt(Ranges.range(sheet, row, 1).getCellEditText()); int numOfDeath = parseInt(Ranges.range(sheet, row, 2).getCellEditText()); String description = Ranges.range(sheet, row, 3).getCellEditText(); double lat = parseDouble(Ranges.range(sheet, row, 4).getCellEditText()); double lng = parseDouble(Ranges.range(sheet, row, 5).getCellEditText()); String content = "<span style=\"color:#346b93;font-weight:bold\">" + state + "</span><br/><span style=\"color:red\">" + numOfCase + "</span> cases<br/><span style=\"color:red\">" + numOfDeath + "</span> death<div style=\"background-color:#E8F5Cf;padding:2px\">" + description + "</div>"; gmarkerArray[row].setContent(content); fluMap.setLat(lat); fluMap.setLng(lng); gmarkerArray[row].setOpen(true); } private void setCellEditText(Sheet sheet, int row, int col, String text) { try { Ranges.range(sheet, row, col).setCellEditText(text); } catch (IllegalFormulaException x) { x.printStackTrace(); } } private double parseDouble(String text) { try { return format.parse(text).doubleValue(); } catch (ParseException e) { return 0D; } } private int parseInt(String text) { try { return format.parse(text).intValue(); } catch (ParseException e) { return 0; } } }