Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/34: Рейтинг темы: голосов - 34, средняя оценка - 5.00
Skittles
1

Запись огромного количества строк из массива в файл Excel

21.01.2010, 15:55. Показов 6453. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Предположим, что есть очень большой массив строковых данных (рассчитываем на пару миллионов, в идеале - 8 с хвостиком). Возможно, этот массив будет разбиваться на более мелкие. Но задача стоит в другом: как этот массив данных записать в файл xls максимально быстро на средней машине?
Реплики по поводу того, что это не целесообразно, не принимаются: у нас очень большая организация, начальство задачу поставило, мне ее нужно решить.

Для справки: Текстовый файл с выгруженным в него массивом этих данных в 700 тыс. строк весит порядка 20 метров.
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.01.2010, 15:55
Ответы с готовыми решениями:

Парсинг строк из огромного текстового файла из конца в начало средствами VBA Excel быстро
Хочу поделиться опытом. Была поставлена задача с помощью VBA Excel читать строки из огромного...

Запись в файл только тех строк, длина которых не менее заданного количества символов
Здравствуйте дорогие форумчане! Вновь прошу вашей помочи. Требуется установить минимальную длину...

Запись в файл массива строк
Доброго времени суток! Нужна небольшая помощь. Требуется записать массив строк string lines в...

Запись всего массива строк в файл
Добрый день! Имеется такой цикл: foreach (var finalRow in list3) { ...

4
683 / 232 / 16
Регистрация: 15.10.2007
Сообщений: 1,247
21.01.2010, 17:37 2
если нужно все очень так быстро пиши на Си,если все таки на джава юзай либу JExcel
0
эволюционирую потихоньку
468 / 466 / 91
Регистрация: 30.06.2009
Сообщений: 1,401
21.01.2010, 19:08 3
Skittles, откуда массив. в каком первоначальном виде он представлен?
соглашусь с Mecid, на Сишнике быстрее получиться, можно даже поэксперементировать.
примерчик исходных данных если не сложно выложите, не обязательно рабочии, просто для понимания, что откуда перегнать. можно типовые данные, а я их сам размножу. если желание попробовать не пройдёт выложу итог сравнения
1
Skittles
22.01.2010, 18:33 4
Mecid, проблема в том, что не в моей компетенции решать на чем писать. стоит задача сделать это на Java. JExcel - библиотека, официально не использующаяся у нас на предприятии, и чтобы ввести ее в "оборот" нужно каждой инстанции доказывать ее необходимость (месяц примерно), а потом еще пару месяцев вводить в эксплуатацию.


TanT, массив на данный момент ввыводится из базы данных (даже не подскажу какая именно СУБД) в текстовый файл. кстати все несколько плачевней: массив из 120 тыс. строк весит 20 метров. но сейчас другими людьми разрабатывается метод, который будет заполнять таблицу в БД. но и тут еще вопрос не решенный. вообще моя задача состоит в том, чтобы извлеченные данные в ArrayList из любого файла (эти данные заранее выгружаются в ArrayList другим методом, написанным другим человеком; код, который на данный момент действует, могу кинуть) записать в в эксэлевский файл, оформленный в своего рода отчет.

структура строк и пример на данный момент выглядят следующим образом:

Ключ - (у или р) статус расцеховки~обозначение ДСЕ~наименование ДСЕ~тип ДСЕ~статус ДСЕ~позиция~уровень входимости~шифр сборки верхнего уровня~статус сборки верхнего уровня~документ выпуска сборки верхнего уровня~ количество на сборочную единицу(техн.)~количество на сборочную единицу(констр.)~обозначение материала~наименование материала~марка материала~тк~параметр кроме (1-если значение атрибута is_krome равно true, 2 - false)~модификация~с~по~цп~ци~цу~цпу~документ изменения расцеховки~дата последнего изменения расцеховки
Примечание: если в атрибуте занесено несколько значений, то данные записываются через символ ";"


НАПРИМЕР: (пример одной строки! а их таких много-много)
у~130.11.5305.1180.000~шайба~[СборЕдиница]~Утвержден~1~1~130.11.5311.1110.000~Утвержден~130-0006708ИИ~1;1~1~0207502278000001~пруток~втх~553;009~1~130.11~101~~207~220;221~21 9~~312-00029ПИ~21 01 2000
р~130.11.5305.1150.000~заглушка~[Деталь]~Разрабатываемый~2~1~130.11.5305.1180.000~Утвержден~130-0006708ИИ~1~1~0207502278000001~пруток~втх~553~2~130.11~101~~207~220;221~248~~312-00029ПИ~21 01 2000
Добавлено через 11 минут
собственно метод, который сейчас "работает", но весьма медленно.

public void WriteXLS(HashMap sheets)
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
public void WriteXLS(HashMap sheets)
   {
      String file_name = "";
      if (!fieldDCE.getText().equals(""))
         file_name = fieldDCE.getText();
      else
      if (!fieldCE.getText().equals(""))
         file_name = fieldCE.getText();
      else
      if (!fieldSTI.getText().equals(""))
         file_name = fieldSTI.getText();
      else
         if (!jComboBox_TK.getSelectedItem().toString().equals(""))
            file_name = "TK_"+jComboBox_TK.getSelectedItem().toString();
      if (file_name.indexOf("*") > -1)
         file_name = IAPOUtils.replaceStr(file_name, "*", "_");
      if (file_name.indexOf(",") > -1)
         file_name = IAPOUtils.replaceStr(file_name, ",", "_");
      System.out.println(file_name);
      FILEXLS = file_name + ".xls";
      FILEPATH = System.getProperty("java.io.tmpdir");
 
      try
      {
         proc.setValue(4);
         labelInf.setText("Формирование XLS файла...");
 
         String name = "";
         int f = 0;
         Object[] keys = null;
         if (sheets != null)
         {
            for (int i = 0; i < keys.length; i++)
            {
               if ( (keys[i]).toString().startsWith("!"))
               {
                  name = "" + keys[i];
                  char buf[] = new char[name.toCharArray().length - 1];
                  name.getChars(1, name.toCharArray().length, buf, 0);
                  name = new String(buf);
                  f = i;
               }
            }
 
            File file = new File(FILEPATH + FILEXLS);
            WritableWorkbook workbook = Workbook.createWorkbook(file);
            WritableFont arial10fontBOLD = new WritableFont(WritableFont.ARIAL, 11, WritableFont.BOLD);
            WritableFont arial10font = new WritableFont(WritableFont.ARIAL, 10);
            WritableCellFormat arial10formatBOLD = new WritableCellFormat(arial10fontBOLD);
            WritableCellFormat arial10format = new WritableCellFormat(arial10font);
 
            arial10formatBOLD.setAlignment(jxl.format.Alignment.CENTRE);
            arial10format.setAlignment(jxl.format.Alignment.CENTRE);
 
            GregorianCalendar d = new GregorianCalendar();
            String str1 = "";
            if (d.get(d.DATE) >= 10)
            {
               str1 = str1 + d.get(d.DATE);
            }
            else
            {
               str1 = str1 + "0" + d.get(d.DATE);
            }
            if (d.get(d.MONTH) + 1 >= 10)
            {
               str1 = str1 + "." + (d.get(d.MONTH) + 1);
            }
            else
            {
               str1 = str1 + "." + "0" + (d.get(d.MONTH) + 1);
            }
            str1 = str1 + "." + d.get(d.YEAR);
 
            WritableSheet sheet = null;
 
            for (int i = 0; i < keys.length; i++)
            {
               //Runtime rt = Runtime.getRuntime();
               //rt.gc();
               ArrayList sheet_i = (ArrayList) sheets.get(keys[i]);
 
               ArrayList list_forPrint = new ArrayList();
                               LinkedList list_in = new LinkedList((ArrayList) sheet_i.get(2));
                               //rt = Runtime.getRuntime();
                               //rt.gc();
                               list_forPrint = listSize(list_in , new LinkedList());
 
               if (i == f)
               {
                  if (list_forPrint.size() <= 1)
                  {
                     if (!jComboBox_TK.getSelectedItem().equals("без ТК"))
                     {
                        name=checkNameSheet(name);
                        sheet = workbook.createSheet( /*"Запрос по " + oboz + "  " +*/name,0);
                        System.out.println("name=="+name);
                     }
                     else
                     {
                        sheet = workbook.createSheet("Запрос по ДСЕ без ТК", 0);
                     }
                  }
 
               }
               else
               {
 
                   if (list_forPrint.size() <= 1)
                  {
                     sheet = workbook.createSheet("Цех " + keys[i], i);
                  }
               }
 
                if (list_forPrint.size() <= 1)
 
               {
 
                 POUtilsPrintXLS print = new IAPOUtilsPrintXLS();
                 if(!jComboBox_TK.getSelectedItem().toString().equals(""))
                    print.numCell=null;
                 else
                 if (fieldCE.getText().equals(""))
                    print.numCell=new int[]{6,7};
                 else
                    print.numCell=new int[]{7,8};
                    print.printToXLSFile(sheet, 4,
                     (String[]) sheet_i.get(0),
                     (int[]) sheet_i.get(1),
                     (ArrayList) sheet_i.get(2));
               }
               else
                               {
                  for (int j = 0; j < list_forPrint.size(); j++)
                  {
 
                     if (i == f)
                     {
                        sheet = workbook.createSheet(oboz + "  " + name + "(" + j + ")", j);
                     }
                     else
                     {
                        sheet = workbook.createSheet("Цех " + keys[i] + "(" + j + ")", j);
                     }
                     sheet.mergeCells(0, 1, 6, 1);
                     Label label2;
                     label2 = new Label(0, 1,
                                        "Запрос по  " + oboz + "  " + name, arial10formatBOLD);
                     sheet.addCell(label2);
                     sheet.mergeCells(0, 2, 6, 2);
                     label2 = new Label(0, 2, "по состоянию на " + str1, arial10format);
                     sheet.addCell(label2);
 
                     IAPOUtilsPrintXLS.printToXLSFile(sheet, 4, (String[]) sheet_i.get(0), (int[]) sheet_i.get(1),(ArrayList) list_forPrint.get(j));
list_in.clear();
 
                  }
                               }
 
               list_forPrint.clear();
 
               sheet.mergeCells(0, 1, 6, 1);
               Label label2;
               if (!jComboBox_TK.getSelectedItem().equals("без ТК"))
               {
                  label2 = new Label(0, 1,
                                     "Запрос по  " + oboz + "  " + name,arial10formatBOLD);
               }
               else
               {
                  label2 = new Label(0, 1,"Запрос по ДСЕ без ТК",arial10formatBOLD);
               }
               sheet.addCell(label2);
               sheet.mergeCells(0, 2, 6, 2);
               label2 = new Label(0, 2, "по состоянию на " + str1,arial10format);
               sheet.addCell(label2);
               sheet_i.clear();
            }
            workbook.write();
            workbook.close();
            proc.setValue(5);
            labelInf.setText("Формирование отчета окончено...");
         }
      }
      catch (IOException ex)
      {
         System.out.println("EROR1");
         ex.printStackTrace();
      }
      catch (WriteException ex)
      {
         System.out.println("EROR2");
         ex.printStackTrace();
      }
      catch (Throwable t)
      {
         System.out.println(t.toString());
         t.printStackTrace();
      }
 
      System.out.println("File " + FILEXLS + " write to " + FILEPATH);
   }


пс: править и сокращать было лень. думаю, для ознакомления вполне сойдет... извините, если что (:
эволюционирую потихоньку
468 / 466 / 91
Регистрация: 30.06.2009
Сообщений: 1,401
24.01.2010, 09:44 5
Skittles, сейчас смотрю ваш ответ и у меня возникают некоторые вопросы по структуре, получается, что для формирования отчёта выполняются следующие действия:
1. вытащить данные из базы, записав из в фаил
2. считать все данные из файла в ArrayList (вот тут вопрос, я правильно понял что все или всётаки построчно?)
3. распарсить\преобразовать строку к виду шаблона и записать в экселевский фаил

имхо, структура должна быть типа
1. вытащить данные из базы, записав из в фаил (раз так повелось)
2. сформировать пустой экселевский документ с указанными настройками + вычислить пути и время + тот интерфейс который используется в вашем примере, только вынести это всё в отдельные методы, в общем произвести всю подготовку
3. запустить один цикл чтения строк из файла, полученного в п.1 и после прочтения каждой строки разбирать её согласно вашим условиям

в этом случае минимум съэкономятся ресурсы на хранение всего объёма данных в памяти и на его чтение.

так же не совсем понятна необходимость анализа jComboBox_TK в процессе преобразования, значение может меняться? или оно всё таки статично с начала преобразования массива данных. если так, то можно провести анализ до преобразования и передовать в итоговый метод разбора соответсвующий флаг. анализ булевской переменной быстрее, чем анализ текста в вашем объекте.

ещё немного можно съэкономить на цикле for (int i = 0; i < keys.length; i++)
если заменить на for (int i = keys.length; --i>=0; ) экономия ощущается при больших значениях keys.length;, однако это применимо, если вам не важен порядок следования

Итого: 1. структурировать код, разбив его на методы: "инициализация", "парсинг"
2. избавиться от массива (если возможно)
3. уменьшить издержки на анализ условий
4. по эксперементировать с временем выполнения методов - завести таймер и вычислять время выполнения метода

в данный момент для меня не совсем очевидны некоторые проверки, так как я не владею всей информацией, в том числе состоянием объектов jComboBox_TK и подобного. в общем высказался, не уверен, что всё конструктивно, поправите если где-то заблуждаюсь
0
24.01.2010, 09:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.01.2010, 09:44
Помогаю со студенческими работами здесь

Запись в файл строк/и в виде байтого массива
public static byte Encrypt(string fileName) { try { ...

Запись массива в файл и чтение из него строк
Задание-составить программу содержащую инфу о фамилии и дате рождения нескольких человек,эту инфу...

Запись в текстовый файл двумерный массива из n-строк и m-столбцов
создать текстовый файл,куда записать двумерный массив из n-строк и m-столбцов

Добавление в ListBox огромного количества данных
Как реализовать добавление в listbox огромного количества данных? Сейчас вылетает ошибка памяти.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru