Заметки веб-работника
7 августа 2007

CSV на веб-страницах

Недавно один мой хороший знакомый, вынужденно ответственный за наполнение сайта фирмы, в которой он работает, пожаловался мне на свой нелегкий труд. Корень зла он видел в таблицах, коих было очень много и работа с которыми отнимала львиную долю редакторского времени. Трудоемким оказался процесс переноса данных из MS Excel (где таблицы хранились и редактировались) на страницы вверенного ему сайта. В CMS, с которой пришлось работать, естественно был предусмотрен «дружественный» режим WYSIWYG, позволяющий напрямую копировать данные из MS Office, однако, как вы наверно догадались, результатом этой легкости был тяжелый HTML-код. Чтобы сохраненные таким образом таблицы не выглядели чужеродными элементами на веб-страницах (а порой, чтобы просто не ломали их) моему приятелю приходилось собственноручно убирать весь мусор и добавлять соответствующие дизайну сайта стилевые классы. Такие вот будни, знакомые многим веб-работягам.

Заканчивая это свое лирическое вступление, скажу, что, конечно же, я не смог остаться безучастным. Обсудив несколько вариантов решения проблемы, в итоге мы остановились на макросе-конвертере и наборе утилит для «чистки» HTML… Среди прочих альтернатив, я рассматривал также идею, которой, собственно, и хотел бы поделиться в этой статье.

Суть ее в следующем: размещать таблицы на веб-страницах, используя компактный текстовый формат CSV. Т.е. помещать эти данные непосредственно в HTML-код, отказавшись от табличных тегов. (Конечно, в идеале поддержку CSV неплохо бы иметь не на клиентском, а на серверном уровне, но сейчас не об этом.) К примеру, так могла бы выглядеть таблица умножения:

<pre class="csv">
,1,2,3,4,5,6,7,8,9,10
1,1,2,3,4,5,6,7,8,9,10
2,2,4,6,8,10,12,14,16,18,20
3,3,6,9,12,15,18,21,24,27,30
4,4,8,12,16,20,24,28,32,36,40
5,5,10,15,20,25,30,35,40,45,50
6,6,12,18,24,30,36,42,48,54,60
7,7,14,21,28,35,42,49,56,63,70
8,8,16,24,32,40,48,56,64,72,80
9,9,18,27,36,45,54,63,72,81,90
10,10,20,30,40,50,60,70,80,90,100
</pre>

Понятно, что браузеры не в состоянии разглядеть в этом наборе символов таблицу, но мы в силах в этом им помочь, используя JavaScript и DOM. Примерный сценарий конвертера может выглядеть так:

function CSVtoHTML()
{
   // Находим все теги pre на странице
   var pre = document.getElementsByTagName("pre");
   
   // Отбираем только те pre, которые имеют класс csv
   var csv = new Array();
   var e = 0;
   for(var i = 0; i < pre.length; i++)
   {
      if (pre[i].className.match(/(\b|\s)csv(\b|\s)/i))
      {
         csv[e] = pre[i];
         e++;
      }
   }

   // Формируем html-таблицы, чтобы заменить ими содержимое тегов pre с классом csv
   for(var i = 0; i < csv.length; i++)
   {
      var table = document.createElement("table");
      // Расщепляем содержимое тега pre на ряды
      var rows = csv[i].innerHTML.split("\n");
      for (e = 0; e < rows.length; e++)
      {
         // Проверяем, чтобы строка не была пустой
         if (rows[e].match(/\s*/) != rows[e])
         {
            var tr = document.createElement("tr");
            // Расщепляем содержимое ряда на ячейки
            var cells = rows[e].split(",");// в данном случае разделитель ","
            for (j = 0; j < cells.length; j++)
            {
               var td = document.createElement("td");
               td.innerHTML = cells[j];
               tr.appendChild(td);
            }
            table.appendChild(tr);
         }
      }
      // Для удобства заменяем тег pre тегом div, который будет оберткой созданной таблицы
      var div = document.createElement("div");
      div.className = csv[i].className;
      csv[i].parentNode.replaceChild(div, csv[i]);
      div.appendChild(table);
      // Без следующей строки IE не отобразит результаты
      div.innerHTML += "";
   }
}

Применение тега pre в качестве обертки для CSV-данных объясняется двумя причинами: во-первых, в этом случае Internet Explorer «не потеряет» в значениях текстовых узлов документа или свойстве innerHTML объектов символы \n и \t, которые мы можем использовать в качестве разделителей; во-вторых, в случае отключения пользователем сценариев, наши данные хотя бы отдаленно будут напоминать таблицы.

Вот, пожалуй, и все. Привязав вызов функции CSVtoHTML к событию onload страницы, мы добьемся нужного результата. Конечно, используя прием, необходимо понимать, что скорость выполнении приведенного сценария напрямую зависит от количества табличных данных на странице. К примеру, на моем домашнем компьютере, IE потребовалось 5 секунд на обработку таблицы в 1000 строк.

Работающий пример можно увидеть здесь.


Теги: JavaScript CSV

 

Оставить отзыв | Комментарии (1)