• Codeby web-security - Курс "Тестирование Веб-Приложений на проникновение с нуля" от команды codeby. Общая теория, подготовка рабочего окружения, пассивный фазинг и фингерпринт, Активный фаззинг, Уязвимости, Пост-эксплуатация, Инструментальные средства, Social Engeneering и многое другое. Подробнее ...

  • Мобильный клиент нашего форума для Android гаджетов доступен в Google Play Market по этой ссылке. Клиент можно скачать с нашего форума по этой ссылке. Последняя версия МК в нашем телеграм канале вот здесь

Про excel, word...

garrick

Lotus team
26.10.2009
911
62
#21
доработки по граблям, на этот раз поставлено ограничение в процессоре до 10 пустых строк, потому как иначе, на нек. шитах, кол-во строк может оказаться 65тыс. (при реальных 85)
Код:
sheet.getLastRowNum()
Не работает?
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 693
307
#22
работает где, в SAX варианте?
там меня процессор не спрашивает, а инициализировать объект еще и для DOM - это опять меморукосампшн
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 693
307
#23
факмоймосх... налажал в логике
позиции в файле неправильные (надож глобальные делать)
Java:
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.model.StylesTable;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
 
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.*;
import java.util.*;
 
/**
* Created by mike on 28.07.14.
*/
public class POI2CSV {
private static final String encoding="UTF-8";
private final Map<String,List<Integer>> arrPathCSV = new HashMap<String,List<Integer>>();
private final Map<String,List<Integer>> arrPathMap = new HashMap<String,List<Integer>>();
private final int BLANK_LIM=10;//limit for blank rows, skip other data (stop additions to corresponding List)
private class CSVmap {
private BufferedWriter osCSV;
private BufferedWriter osMAP;
private final File tempcsv;
private final File tempmap;
 
public CSVmap(String xName) throws IOException {
xName=xName.replaceAll("\"","");
tempcsv = File.createTempFile(xName, ".csv");
tempmap = File.createTempFile(xName, ".map");
osCSV= new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempcsv),encoding));
osMAP= new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempmap), encoding));
}
 
public void close() throws IOException {
osCSV.close();
osMAP.close();
}
 
public void write(String cellReference, String formattedValue) throws IOException {
//			System.out.println(cellReference+SEP);
char SEP = ';';
osMAP.write(cellReference + SEP);
osCSV.write(formattedValue + SEP);
}
 
public void newLine() throws IOException {
osMAP.newLine();
osCSV.newLine();
}
 
public String getTempcsv() {
return tempcsv.getAbsolutePath();
}
 
public String getTempmap() {
return tempmap.getAbsolutePath();
}
 
}
public void parseExcel(File file) throws IOException {
 
OPCPackage container;
try {
container = OPCPackage.open(file.getAbsolutePath());
ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(container);
XSSFReader xssfReader = new XSSFReader(container);
StylesTable styles = xssfReader.getStylesTable();
XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
while (iter.hasNext()) {
InputStream stream = iter.next();
//file.getName()+'_'+iter.getSheetName()
CSVmap csvmap=new CSVmap(file.getName()+'_'+iter.getSheetName());
processSheet(styles, strings, stream, csvmap);
stream.close();
csvmap.close();
}
} catch (InvalidFormatException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (OpenXML4JException e) {
e.printStackTrace();
}
 
}
 
protected void processSheet(StylesTable styles, ReadOnlySharedStringsTable strings, InputStream sheetInputStream, final CSVmap csvmap) throws IOException, SAXException {
//duplicate for size in newLine
String lineSeparator = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
//length in bytes for default encoding, suppose UTF-8
final int lnsepLen=lineSeparator.getBytes(encoding).length;
final int sepLen=1;
InputSource sheetSource = new InputSource(sheetInputStream);
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
final List <Integer> arrmap=new ArrayList<Integer>();
final List<Integer> arrdata=new ArrayList<Integer>();
arrPathMap.put(csvmap.getTempmap(), arrmap);arrPathCSV.put(csvmap.getTempcsv(), arrdata);
 
try {
SAXParser saxParser = saxFactory.newSAXParser();
XMLReader sheetParser = saxParser.getXMLReader();
ContentHandler handler = new XSSFSheetXMLHandler(styles, strings, new XSSFSheetXMLHandler.SheetContentsHandler() {
int idx =0;//only one index for arrmap, arrdata
int blankcnt=0;//see BLANK_CNT
int lenmap=0, lendata =0;
 
public void startRow(int rowNum) {
if (blankcnt>BLANK_LIM) return;
arrmap.add(0);arrdata.add(0);
idx =arrmap.size()-1;
}
 
public void endRow() {
try {
if (blankcnt>BLANK_LIM) return;
csvmap.newLine();
if (arrmap.get(idx)<=sepLen) {
blankcnt++;}
else{blankcnt=0;} //check only one array (as array sizes are equal)
lenmap+=arrmap.get(idx) + lnsepLen;
arrmap.set(idx, lenmap);
lendata+=arrdata.get(idx) + lnsepLen;
arrdata.set(idx, lendata);
} catch (IOException e) {
e.printStackTrace();
}
}
 
public void cell(String cellReference, String formattedValue) {
if (blankcnt>BLANK_LIM) return;
try {
formattedValue=formattedValue.replaceAll("[\n\r]", "|");
csvmap.write(cellReference, formattedValue);
//set data length for arrays
int len=arrmap.get(idx) + cellReference.getBytes(encoding).length;
arrmap.set(idx,len + sepLen);
len=arrdata.get(idx) + formattedValue.getBytes(encoding).length;
arrdata.set(idx,len + sepLen);
} catch (IOException e) {
e.printStackTrace();
}
}
 
public void headerFooter(String text, boolean isHeader, String tagName) {
 
}
 
},
//new DataFormatter(new Locale("en","UK")),
false//means result instead of formula
);
sheetParser.setContentHandler(handler);
sheetParser.parse(sheetSource);
//			System.out.println("arrmap size:" + arrmap.size()+";->" +csvmap.getTempmap());
} catch (ParserConfigurationException e) {
throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage());}
}
 
public Integer[] getArrMap(String key){
/*		int[] ret= new int[arrmap.size()];
int i = 0;
for (Integer e : arrmap)
ret[i++] = e;
return ret;
 
*/
List<Integer> arr=arrPathMap.get(key);
System.out.println("map index size:" + arr.size());
return arr.toArray(new Integer[0]);
}
 
public Integer[] getArrData(String key){
List <Integer> arr=arrPathCSV.get(key);
System.out.println("csv index size:"+arr.size());
return arr.toArray(new Integer[0]);
}
 
public String[] getArrPathCSV() {
Set<String> keys=arrPathCSV.keySet();
List<String> forsort=new ArrayList<String>(keys);
java.util.Collections.sort(forsort);
return forsort.toArray(new String[0]);
}
 
public String[] getArrPathMap() {
Set<String> keys=arrPathMap.keySet();
List<String> forsort=new ArrayList<String>(keys);
java.util.Collections.sort(forsort);
return forsort.toArray(new String[0]);
}
 
public static void main(String args[]){
POI2CSV inst=new POI2CSV();
try {
System.out.println(args[0]);
inst.parseExcel(new File(args[0]));
String[] mappath=inst.getArrPathMap();
String[] csvpath=inst.getArrPathCSV();
int idx=0;
Integer[] testmap=inst.getArrMap(mappath[idx]);Integer[] test=inst.getArrData(csvpath[idx]);
System.out.println(csvpath[idx]);
System.out.println(mappath[idx]+"; array size:" + mappath.length);
System.out.println(test[3] + "; array size:" + test.length);
System.out.println(testmap[3] + "; array size:" + testmap.length);
RandomAccessFile raf = new RandomAccessFile(mappath[idx], "r");
raf.seek(testmap[3]);
System.out.println("line #5 -->" + raf.readLine());
raf.close();
raf=new RandomAccessFile(csvpath[idx], "r");
raf.seek(test[3]);
FileDescriptor fd = raf.getFD();
FileReader	 fr = new FileReader(fd);
BufferedReader br = new BufferedReader(fr);
System.out.println("csv line #5 -->" +br.readLine());
 
 
} catch (IOException e) {
e.printStackTrace();
}
}
}
кусок
Java:
						lenmap+=arrmap.get(idx) + lnsepLen;
arrmap.set(idx, lenmap);
lendata+=arrdata.get(idx) + lnsepLen;
arrdata.set(idx, lendata);
был без накопления позиции

Добавлено: и вот пара особенностей...
ячейки с переводом каретки - меняю на пайп
даты из хехеля идут в в
Для просмотра контента необходимо: Войти или зарегистрироваться
формате mm/dd/yy - вменяемого способа исправить не нашёл, а лопатить уровнем ниже - нет желания. Потому, затычка уже в ЛС:
Код:
					'если строка и дата содержит разделители /
'предполагаем формат США mm/dd/yy
'при неуказанном формате даты Excel POI SAX выведеn строку в таком формате
If DataType(v)=V_STRING Then
Dim arr:arr=Split(v, DAT_SEP_USA)
If UBound(arr)<>2 Then
Error 1024, CM_WRONGTYPE4DAT _
&{at idx:} &CStr(idx) &{;val:} &CStr(v)
End If
v=DateNumber(arr(2),arr(0),arr(1))
End If
Добавлено: че будет через 100 лет с затычкой :angry2: ?! ведь год краткий (остается надеяться что через 100 лет эхеля не будет)
 
Последнее редактирование модератором:

savl

Lotus team
28.10.2011
2 138
105
#24
lmike
Спасибо за твои труды, но может уже релиз сделаешь?)
Вот честно, мне не особо хочется в чужой шаблон вставлять чужой же код, а то наманьячу...
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 693
307
#25
оттестю и выложу обязательно
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 693
307
#26
ну вот и "релиз", в моем понятии - бетта :angry2: (тестил только я, на разных данных)
приделал автоудаление файлов в агенте
в коде много закоменчено, в ходе тестов создавал, есть Print, есть DbgMsg
последний зависи от Debug (глобальная переменная)
набаянил кучу классов, но где-то оставил кондово (типа - возврат массива с двумя значениями - строка;колонка)
в несовсем очевидных местах оставлял каменты, но не усердствовал по комментированию кода :)

Добавлено: проводил тест на 150 листах с данными по 100 строк, сам POI отрабатывает быстро, основное время на нотуса
получается ок 20тыс доков создается и их компутеВизФорм...
можно сократить время создав один док, просчитав его, а далее - копировать все айтемы из документов коллекций

Добавлено: есть особенность (очередная) - хранения процентов будет деленным на 100 (что нормально, но нужно учитывать)

Добавлено: помимо прохода по строкам (тупого) можно указывать привязку поля к конкретной ячейке (добавлено в конфигурацию и ее класс)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 693
307
#27
переделал форму загрузки (выложу позже - там на либы скомпоновать нужно) - позволяет указать подчиненную конфигурацию
importPOI1.png importPOI2.png
 

Вложения

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 693
307
#28
некоторые обобщения под код :)
вопрос / ответ:
  • для чего эта библиотека (библиотеки/базы) / потребность перенести данные из Excel в нотес и обратно - не являются редкой задачей (как и вобщем - обмен с МСО)
  • почему именно POI / интерфейс к продуктам МСО, в этой библиотеке более-менее отработан и существует в разных вариантах по доступу, можно обеспечить перевод в др. формат (FOP например, а далее в ПДФ)
  • почему в текущей реализации (моей библиотеки) использован бридж LS2J / связанно с доступом к памяти и интерграцией в сущ. кодом LS (полагаю он есть у многих). Доступ к памяти специфичен для jvm тем, что требует предварительной настройки (казания кол-ва в ini файле), в тоже время, в LS доступна память до 2Гб. НО В активно развиваемой технологии xPages - несколько др. подход.... Здесь обсуждается только "классический" вариант использования jvm
  • почему используется именно SAX версия / затраты памяти на воссоздание java объектов (в случае с "обычным" вариантом) могут оказаться слишком большими, с чем я и сталкивался (1Гб для jvm не хватило)
  • почему индексные массивы передаются полностью (из jvm в LS), а не используется доступ по индексу / ограничение накладываемое Integer в LS действительно "мешает" обработать файлы, с кол-вом строк > 65К, но весь LS построен на этих ограничениях (поля, индексы, объем хранимой инфы в переменных и т.п.). При это нужно понимать - файлы xlsx большого объема переносить в Домино может оказаться нецелесообразным. В текущем подходе создаются доки 1->1 (строка на док) и создание большого кол-ва документов вызывает некоторую осторожность B). Таки можно реализовать иначе (получать значение по индексу напрямую из jvm) :(
  • чем чревато передача большего кол-ва индексов, чем допустимо в LS массивах / эффектом java object is Null, или выпадением нотусятины в корку (core dump или NSD)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 693
307
#29
к теме относится только как эксель :)
оставлю здесь http://stackoverflow.com/a/4107352
ломаем хухель пароль на VBA
типа пошаговое описание моего варианта...
у меня был .xlsb, переименовал (ну это понятно) и распаковал зип
файло находилось по пути xl/vbaProject.bin
открыл с пом. okteta (на бубунте в стандартных репах), на виндядке - читать по ссылке
нашел DPB= и перебил на DPx=
открыл, зашел в VBA (Alt-F11) сохранил/закрыл
не пытаться открывать код без переоткрытия!
Это метод "противодействия" говнокодерам, кот. паролем защищают свои поделия (лучи поноса им) :)
 
Вверх Снизу