Электронную таблицу - на веб-страницу

Проблема преобразования электронных таблиц в веб-контент не нова. Многие, не мудрствуя лукаво, выгружают свои прайс листы на сайты в бинарном виде, что не делает им чести. Кто-то сохраняет документы в формате html прямо из офисных приложений, что тоже не есть хорошо. Те, кто знаком с серверными технологиями, прикручивают экселевские прайсы к сайтам с помощью ODBC и других хитрых механизмов. А ведь есть старинный способ, который в сочетании с мощью современных фреймворков (в частности, GWT) дает элегантное решение…

В давние времена, когда электронные таблицы были еще зачастую консольными приложениями, широко использовался файловый формат CSV — Coma Separated Values (= значения, разделенные запятыми). Например, создадим такую таблицу:



Сохраним ее в CSV и откроем в простом текстовом редакторе:

"Тема занятия","Время, акад./ч"
"История и классификация языков программирования",2
"Язык программирования C, его достоинства и недостатки",1
"Объектно-ориентированные языки программирования. C++",1


Ничего не напоминает? А так:

[["Тема занятия","Время, акад./ч"],
["История и классификация языков программирования",2],
["Язык программирования C, его достоинства и недостатки",1],
["Объектно-ориентированные языки программирования. C++",1]]

?

Да это же JSON! Чтобы превратить CSV-файл в JSON-описание двухмерного массива нужно просто добавить кое-где квадратные скобки. Основываясь на этой простой идее, я написал GWT-класс для формирования веб-таблиц из CSV-ресурсов. Последние можно просто выгружать по FTP на самый примитивный хостинг по мере того, как содержимое электронных таблиц будет меняться.

package net.sf.lab3f.gwt.csvtable.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.dom.client.TableElement;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.dom.client.TableCellElement;

import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;

import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;

import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.Response;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;

import com.google.gwt.dom.client.Style.Unit;

public class Main extends SimplePanel{ 
 public Main(String file){
  Element holder = getElement();     
  Element tblEl = DOM.createTable();
  tblEl.getStyle().setProperty("width", "100%");
  holder.appendChild(tblEl);
  final TableElement table = TableElement.as(tblEl);
  RequestBuilder tabsBuilder = new RequestBuilder(RequestBuilder.GET, GWT.getModuleBaseURL() + file);
  try{
   tabsBuilder.sendRequest("", new RequestCallback(){
    public void onResponseReceived(Request req, Response resp){
     String rsp  = resp.getText();
     rsp = "[[" + rsp.replace('\n', ']').replaceAll("]", "],[").replaceAll("\\],\\[$", "]]"); 
     JSONArray data = JSONParser.parse(rsp).isArray(); //     
     for(int i = 0; i < data.size(); i++){
      JSONArray jsa = data.get(i).isArray();
      Element el = DOM.createTR();
      TableRowElement row = TableRowElement.as(el);
      table.appendChild(row);
      for(int j = 0; j < jsa.size(); j++){
       el = i == 0 ? DOM.createTH() : DOM.createTD();
       el.setInnerText(dequote(jsa.get(j).toString()));
       el.setClassName("gwt-CsvTableCell-" + j + "-" + (i % 2 == 0 ? "even" : "odd"));
       row.appendChild(el);
      } 
     }	     
    } 
    public void onError(Request req, Throwable thr){Window.alert(thr.toString());}
   });	  
  } 
  catch(Exception ex){}
 }	 

 private String dequote(String s){
  String r = s.trim();
  if(r.startsWith("\""))r = r.substring(1);
  if(r.endsWith("\""))  r = r.substring(0, r.length() - 1);
  return r;
 }	 
}


Результат выглядит примерно так:

Комментарии (2)

RSS свернуть / развернуть
+
0
Элегантно. При экспорте в html openoffice до сих пор генерирует ужасающий код.
avatar

Sergei_T

  • 19 августа 2011, 10:00
+
0
Можно, кстати, придумать какой-нибудь плагин к OpenOffice, который будет выгружать csv-файл по ftp прямо на сайт. А можно замонтировать ftp-директорию посредством fuse и туда сохранять.
avatar

yababay

  • 19 августа 2011, 10:04

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.