powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
23 сообщений из 23, страница 1 из 1
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39131896
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробовал открыть xslx просто:
Код: java
1.
Workbook wb = WorkbookFactory.create(new File(FileName));


Вылетает по аутофмемори.
Посмотрел , народ пишет, надо использовать SXSSFWorkbook, но примера, как читать с пом. SXSSFWorkbook не нашел, в основном примеры записи большого xslx, с чтением непонятно.
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39131932
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39131951
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpashaв гугле забанен?
Окак:
You can't. SXSSFWorkBook is write only, it doesn't support reading
For low memory reading of .xlsx files, you should look at the XSSF and SAX EventModel documentation


Капец, то есть нужно некий SAX ковырять?
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39131958
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSchpashaв гугле забанен?
Окак:
You can't. SXSSFWorkBook is write only, it doesn't support reading
For low memory reading of .xlsx files, you should look at the XSSF and SAX EventModel documentation


Капец, то есть нужно некий SAX ковырять?
там в ответе и ссылка есть
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39131963
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpashaтам в ответе и ссылка есть
Ага видел. Курю потихоньку. Спасиб )
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39132016
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробую тот пример:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
	public void processOneSheet(String filename) throws Exception {
                File f = new File(filename);
                if (f.exists()) 
                    System.out.println("yes");

		OPCPackage pkg = OPCPackage.open(filename);
		XSSFReader r = new XSSFReader(pkg);
		SharedStringsTable sst = r.getSharedStringsTable();

		XMLReader parser = fetchSheetParser(sst);

		// To look up the Sheet Name / Sheet Order / rID,
		//  you need to process the core Workbook stream.
		// Normally it's of the form rId# or rSheet#
		InputStream sheet2 = r.getSheet("rId2");
		InputSource sheetSource = new InputSource(sheet2);
		parser.parse(sheetSource);
		sheet2.close();
	}


Ломается на getSharedStringsTable:
автор Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObject
at org.apache.poi.xssf.eventusermodel.XSSFReader.getSharedStringsTable(XSSFReader.java:82)


Плюс не пропускает XSSFRichTextString и getEntryAt в
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
public void endElement(String uri, String localName, String name)
				throws SAXException {
			// Process the last contents as required.
			// Do now, as characters() may be called more than once
			if(nextIsString) {
				int idx = Integer.parseInt(lastContents);
				lastContents = new XSSFRichTextString(sst.getEntryAt(idx)) .toString();
				nextIsString = false;
			}

			// v => contents of a cell
			// Output after we've seen the string contents
			if(name.equals("v")) {
				System.out.println(lastContents);
			}
		}


Говорит, вроде как неправильный тип.
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39132077
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почитал.
Подключил xmlbeans-2.3.0.jar, saxon9.jar, saxon9-dom.jar пошло дальше.
Теперь ломаемся на
Код: java
1.
XMLReader parser = fetchSheetParser(sst);


org.xml.sax.SAXException: SAX2 driver class org.apache.xerces.parsers.SAXParser not found
Почитал.
Подключил из xerces: xsercesiml.jar и xml-apis.jar
Вроде зашуршало.
Но это ж какая-то беда постоянно так кодить, копаясь в гугле, когда надо сваять что-то новое неужели все так живут? )
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39132091
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теперь такая засада.
parser.parse(sheetSource);
Начинает читать файл сначала и до конца.
При этом адреса ячеек выводит типа A1, B1, C1 и т.д.
Можно ли как-то обращаться по конкретному адресу ячейки при чем по номерам ячеек типа (1,1) (2,1) и т.д.?
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39132212
Garrick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSВылетает по аутофмемори.

А просто побольше памяти выделить не пробовали? -Xmx512m?
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39132223
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GarrickА просто побольше памяти выделить не пробовали? -Xmx512m?
Почему-то сразу отбросил этот вариант, т.к. при открытии этого файла ява-процесс отожрал больше гига каким-то чудом, хотя в файле всего около 100т записей (полей много правда), предположительно могут встречаться и файлы с бОльшим количеством.
Попробую увеличить, но если через SAX, выходит, что прежде надо будет например или закачать в память, но лучше наверно конвертировать хотя бы в обычный текстивик, а потом уже заливать (в базу надо закачать)?
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39132847
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже, придется сначала перелить например в xls или ods, а потом уже работать, обращаясь по адресам ячеек :(
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39132929
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну да. Кто ж в xls засунет 100к записей. Есть еще вариант перелить все во временную табличку с двумя полями:
1. индексированное поле - адрес ячейки
2. значение
Может есть вариант создать индексированный файл? ) Можно самому намутить файл и индекс к нему или что-то навроде того, но тоже видится каким-то бредовым решением.
И вообще все это не вписывается в общую модель, т.е. хотелось бы иметь общий интерфейс для обращения ко всем типам файлов (опенофис и мсексель)...
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39133022
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я правильно понял, ты забил на saxparser, потому что он тебе ячейки не в том формате выкидывает и теперь сидишь тут изобретаешь варианты один чудней другого?
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39133113
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpashaя правильно понял, ты забил на saxparser
Не совсем забил, но почти.
То есть взял код из примера:
Код: 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.
package xlxtest;

import java.io.File;
import java.io.InputStream;

import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

public class Xlxtest {
	public void processOneSheet(String filename) throws Exception {
                File f = new File(filename);
                if (f.exists()) 
                    System.out.println("yes");

		OPCPackage pkg = OPCPackage.open(filename);
		XSSFReader r = new XSSFReader(pkg);
		SharedStringsTable sst = r.getSharedStringsTable();

		XMLReader parser = fetchSheetParser(sst);
                //String s = parser.getContentHandler().startElement();

		// To look up the Sheet Name / Sheet Order / rID,
		// you need to process the core Workbook stream.
		// Normally it's of the form rId# or rSheet#
		InputStream sheet2 = r.getSheet("rId1");
		InputSource sheetSource = new InputSource(sheet2);
		parser.parse(sheetSource);
		sheet2.close();
	}

	public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
		XMLReader parser =
			XMLReaderFactory.createXMLReader(
					"org.apache.xerces.parsers.SAXParser"
			);
		ContentHandler handler = new SheetHandler(sst);
		parser.setContentHandler(handler);
		return parser;
	}

	/** 
	 * See org.xml.sax.helpers.DefaultHandler javadocs 
	 */
	private static class SheetHandler extends DefaultHandler {
		private SharedStringsTable sst;
		private String lastContents;
		private boolean nextIsString;
		
		private SheetHandler(SharedStringsTable sst) {
			this.sst = sst;
		}
		
		public void startElement(String uri, String localName, String name,
				Attributes attributes) throws SAXException {
			// c => cell
			if(name.equals("c")) {
				// Print the cell reference
				System.out.print(attributes.getValue("r") + " - ");
				// Figure out if the value is an index in the SST
				String cellType = attributes.getValue("t");
				if(cellType != null && cellType.equals("s")) {
					nextIsString = true;
				} else {
					nextIsString = false;
				}
			}
			// Clear contents cache
			lastContents = "";
		}
		
		public void endElement(String uri, String localName, String name)
				throws SAXException {
			// Process the last contents as required.
			// Do now, as characters() may be called more than once
			if(nextIsString) {
				int idx = Integer.parseInt(lastContents);
				lastContents = new XSSFRichTextString(sst.getEntryAt(idx)) .toString();
				nextIsString = false;
			}

			// v => contents of a cell
			// Output after we've seen the string contents
			if(name.equals("v")) {
				System.out.println(lastContents);
			}
		}

		public void characters(char[] ch, int start, int length)
				throws SAXException {
			lastContents += new String(ch, start, length);
		}
	}
	
	public static void main(String[] args) throws Exception {
		Xlxtest example = new Xlxtest();
		example.processOneSheet("d:\\test.xlsx");
	}
}


Который в startElement вроде как ловит адрес ячейки, в endElement содержимое ячейки, но в целом походу метод parse читает подряд весь файл и при этом не нашел возможности обращаться к ячейкам поадресно, а изучать весь этот SAX (если там вообще есть такая возможность) времени пока нет, может позже. Поэтому пока пишу вывод во временную табличку в БД, а уже с ней буду работать по ячейкам :(
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39133286
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да. Заливать в базу файл в 100к записей пусть даже в 20 полей, разворачивая его "вертикально" по одной ячейке и получая на выходе 2млн записей - это бред конечно. Остается или как-то научиться адресоваться к ячейкам c помощью SAX или не трахать себе мозг, а поставить MSOffice и открывать файлы им, но на машине с линуксом тоже не вариант походу.
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39133376
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я может чего проглядел, зачем нужно адресовать целенаправленно, если задача была прочитать и залить в базу? принцип работы saxparser-а всега один и тот же, он кидает тебе всю инфу, которая есть, ты выбираешь себе то что надо. Не прямая адресация "дай мне ячейку 1,2", а фильтрация - "если ячейка 1,2 -> то"
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39133451
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpashaя может чего проглядел, зачем нужно адресовать целенаправленно, если задача была прочитать и залить в базу? принцип работы saxparser-а всега один и тот же, он кидает тебе всю инфу, которая есть, ты выбираешь себе то что надо. Не прямая адресация "дай мне ячейку 1,2", а фильтрация - "если ячейка 1,2 -> то"
Да. Это понял, если в этом паресере нет прямой адресации, то не очень.
Прежде чем заливать данные в БД, мне необходимо сопоставить поля (т.к. файлы не имеют единого формата), поэтому прежде перебираю листы файла (данные могут быть на любом листе), по контексту ищу нечто похожее на заголовок (необязательно он с первой строки и не обязательно занимает одну строку и т.д.), сопоставляю поля файла с полями в таблице БД (могут переставляться местами, добавляться новые) и дальше пошел читать все, что ниже заголовка, заливать в БД.

chpashaа фильтрация - "если ячейка 1,2 -> то
Да. Можно конечно и в этом варианте точно так же вычленить заголовок, сделать кроссировку и заливать дальше, просто помимо того, что нет единого формата файлы в принципе могут быть разными xls, ods, xlsx и для всех трех в принципе запилил общий интерфейс, только внутренняя реализация самого чтения отличалась, сейчас же из-за того, что не выходит адресоваться напрямую для xlsx эта универсальность немного рушится или ее надо переделывать, то есть типа убирать общий метод условно GetCell, а делать более глобальные методы классов типа LoadIntoDataBase. Т.е. до этого у меня была общая процедура разбора заголовков для всех типов файлов.
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39133478
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSДа. Это понял, если в этом паресере нет прямой адресации, то не очень.
А как ты себе такой парсер представляешь? Ты ему координаты, а он такой бац и по ним вычислил позицию в файле где читать значение? Это же не база данных.
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39133495
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может есть аналог JRSwapFileVirtualizer как в Jasper?
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39133513
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczЭто же не база данных
Понимаю конечно, но надеялся на чудо )))
Всем спасибо, придется делать xlsx разбор "на лету"
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39139902
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати как быть с датами? Они ж читаются просто как цифры.
Если посмотреть что пишут про формат хранения даты в екселе, то типа это кол-во дней, начиная с 01.01.1900.
В моем же случае опытным путем видно, что это кол-во дней, начиная с 30.12.1899.
Это что может меняться от файла к файлу ) Или от версии к версии офиса? )
Как быть в общем с датой? )
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39139926
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот еще нашел
Тип Date
При работе с этим типом данных следует иметь ввиду, что VBA-типы Date не являются такими же типами, как в рабочих листах Excel, хотя во многом и схожи с ними. Например, базовой датой для VBA-типа Date является 30 декабря 1899 года, а в Excel - 1 января 1900 года
И с огромной долей вероятности xlsx заполнен именно с помощью vba-макроса, а учитывая вышесказанное, вроде как и объясняется почему в ячеках числа с отсчетом с 1899-го. Но это ж трыднец какой-то :(
Вот пришел к тебе MSxlsx и как понять программно то ли с 1900, то ли 1899 циферки дат?? )
...
Рейтинг: 0 / 0
POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
    #39140047
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все-таки придется отталкиваться от даты 30.12.1899 + число ячейки в файле.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / POI и xlsx OutOfMemory открыть с пом. SXSSFWorkbook
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]