I am trying to search a query from Apache Lucene index. The search is returning a large amount of result, I have to fill the result in JTable using Swing. I am using the loop to extract the object row from Apache Lucene index.
For the above reason if there are thousands of the record then it takes time to fill the records in table , I am using the following code. Is there any other way to achieve the task without running the loop?
try { File indexDir= new File("path of the file")
Directory directory = FSDirectory.open(indexDir);
IndexSearcher searcher = new IndexSearcher(directory, true);
int maxhits=1000000;
QueryParser parser1 = new QueryParser(Version.LUCENE_36, "field",
new StandardAnalyzer(Version.LUCENE_36));
Query qu=parser1.parse("texttosearch");
TopDocs topDocs = searcher.search(, maxhits);
ScoreDoc[] hits = topDocs.scoreDocs;
len = hits.length;
int docId = 0;
Document d;
Vector column_name=new Vector();
column_name.addElement("title");
column_name.addElement("");
// For All Rows Data
Vector row=new Vector();
String filename="";
String titlee="";
Vector newRow=new Vector();
for ( i = 0; i<len; i++) {
docId = hits[i].doc;
d = searcher.doc(docId);
filename= d.get(("fpath"));
titlee=d.get("title");
newRow= new Vector();
newRow.addElement(titlee);
newRow.addElement(filename);
row.addElement(newRow);
}
DefaultTableModel model= new DefaultTableModel(row, column_name);
table.setModel(model);
}
catch(Exception ex)
{
ex.printStackTrace();
}
small mistakes sometimes creates big troubles
Vector row = new Vector(); should be Vector<Vector<Object>> row = new Vector<Vector<Object>>();
first line in loop for (i = 0; i < len; i++) { must be newRow = new Vector();
pseudo code
for (i = 0; i < len; i++) {
// must be otherwise first Vector is added forever!!!
newRow = new Vector();
//loop, add elements to one dimensional Vector
// add 1D Vector to 2D Vector used and implemented in JTables API
row.addElement(newRow);
}
I'd be to define variable in form Vector<Object> newRow = new Vector<Object>();
everything important is described in Oracle turorial How to use Tables
Related
I am using selenium and java to scrape data on a specific site, but with the code below I can write only 1 data in the spreadsheet, it is not recording all the data in sequence as it should be.
I can't structure the loop correctly.
public void gravarDados() throws IOException {
int i = 0;
File localPlanilha = new File("tools/resultado_da_pesquisa.xlsx");
FileInputStream planilhaExistente = new FileInputStream(localPlanilha);
XSSFWorkbook plan = new XSSFWorkbook(planilhaExistente);
XSSFSheet sheetExistente = plan.getSheetAt(0);
for (int i = 0; i < inicio; i++) {
// Writing data
sheetExistente.getRow(2).createCell(5).setCellValue(TitulosHoteis.get(i).getText());
FileOutputStream fechandoArquivo = new FileOutputStream(localPlanilha);
plan.write(fechandoArquivo);
}
}
Currently you are getting only the 0th element.
You need to iterate the below with a for loop
TitulosHoteis.get(i).getText());
to write the result to rows and columns.
Please modify it as below
for (int i = 0; i < inicio; i++) {
// Writing data
sheetExistente.getRow(i+2).createCell(5).setCellValue(TitulosHoteis.get(i).getText());
}
FileOutputStream fechandoArquivo = new FileOutputStream(localPlanilha);
plan.write(fechandoArquivo);
As mentioned before you're not iterating over the rows as the row number stays the same in your code, however there is also another problem with your code. You need to check if a row exists and if it doesn't create it before you can set a cell value of that row.
It should look something like this:
for (int i = 0; i < inicio; i++) {
Row row = sheetExistente.getRow(2+i);
if (row == null) sheetExistente.createRow(2+i);
sheetExistente.getRow(2 + i).createCell(5).setCellValue(TitulosHoteis.get(i).getText());
}
I'm receiving an error when opening my OpenXML created spreadsheet. The error is as follows.
repaired record : xl/worksheets/sheet.xml partial cell information
private void SavexlsExcelFile(String fullPathName)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Create(fullPathName, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Columns columns = new Columns();
worksheetPart.Worksheet.AppendChild(columns);
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Sheet" };
sheets.Append(sheet);
workbookPart.Workbook.Save();
sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
List<List<string>> dataRow = new List<List<string>>();
List<String> dtRow = new List<String>();
Row row = new Row();
for (int i = 0; i < dataGridView1.RowCount; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
if (i == 0)
{
Cell dataCell = new Cell();
dataCell.DataType = CellValues.String;
CellValue cellValue = new CellValue();
cellValue.Text = dataGridView1.Columns[j].Name;
dataCell.StyleIndex = 2;
dataCell.Append(cellValue);
row.AppendChild(dataCell);
//dataColumn.Add(dataGridView1.Columns[j].Name);
}
dtRow.Add(dataGridView1.Rows[i].Cells[j].Value.ToString());
}
}
dataRow.Add(dtRow);
sheetData.AppendChild(row);
row = new Row();
foreach (List<string> datarow in dataRow)
{
row = new Row();
foreach(string dtrow in datarow)
{
row.Append(ConstructCell(dtrow, CellValues.String, 2));
}
sheetData.AppendChild(row);
}
worksheetPart.Worksheet.Save();
}
}
private Cell ConstructCell(string value, CellValues dataType, uint styleIndex = 0)
{
return new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType),
StyleIndex = styleIndex
};
}
There are 2 issues here that I can see. The first is that your use of Columns is incorrect. You should use Columns if you wish to control things such as the width of a column. To use Columns correctly, you'll need to add child Column elements. For example (taken from here):
Columns columns = new Columns();
columns.Append(new Column() { Min = 1, Max = 3, Width = 20, CustomWidth = true });
columns.Append(new Column() { Min = 4, Max = 4, Width = 30, CustomWidth = true });
In your sample you could just remove the following two lines
Columns columns = new Columns();
worksheetPart.Worksheet.AppendChild(columns);
The second issue is the StyleIndex you are using; the style doesn't exist in your document because you haven't added it. The easiest thing to do here is to just remove the StyleIndex altogether.
When debugging files like this, it's always worth looking at the OpenXml Productivity Tool. You can open a generated file in the tool and validate it to see what errors you have in your file.
All the text in Excel is stored under a shared string table. You need to insert the string in shared string table:
string text = dataGridView1.Columns[j].Name;
cell.DataType = CellValues.SharedString;
if (!_spreadSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Any())
{
_spreadSheet.WorkbookPart.AddNewPart<SharedStringTablePart>();
}
var sharedStringTablePart = _spreadSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
if (sharedStringTablePart.SharedStringTable == null)
{
sharedStringTablePart.SharedStringTable = new SharedStringTable();
}
//Iterate through shared string table to check if the value is already present.
foreach (SharedStringItem ssItem in sharedStringTablePart.SharedStringTable.Elements<SharedStringItem>())
{
if (ssItem.InnerText == text)
{
cell.CellValue = new CellValue(ssItem.ElementsBefore().Count().ToString());
SaveChanges();
return;
}
}
// The text does not exist in the part. Create the SharedStringItem.
var item = sharedStringTablePart.SharedStringTable.AppendChild(new SharedStringItem(new Text(text)));
cell.CellValue = new CellValue(item.ElementsBefore().Count().ToString());
I'm showing the method were the JTable is constructed, the error is when adding the rows inside the for (int i = 1; i <= numero_columnas; i++) loop, or the way the DefaultTableModel model = new DefaultTableModel(); is declared, I can't find the error.
public void verTablaTable (Connection db, String nombre) throws Exception{
Statement stmt=db.createStatement();
ResultSet sst_ResultSet = stmt.executeQuery("SELECT * FROM "+nombre);
ResultSetMetaData md = sst_ResultSet.getMetaData();
int numero_columnas = md.getColumnCount();
DefaultTableModel model = new DefaultTableModel();
for (int i=1;i<=numero_columnas; i++){
model.addColumn(md.getColumnName(i));
}
JTable tabla =new JTable(model);
DefaultTableModel model1 = (DefaultTableModel) tabla.getModel();
Vector row = new Vector();
row.setSize(numero_columnas);
while (sst_ResultSet.next()){
for (int i = 1; i <= numero_columnas; i++){
row.set(i-1,sst_ResultSet.getString(i));
}
model1.addRow(row);
}
tabla.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane sp_vertabla = new JScrollPane(tabla);
sp_vertabla.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sp_vertabla.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
sp_vertabla.setBounds(50,30,700,500);
JPanel cont_vertabla = new JPanel(null);
cont_vertabla.setPreferredSize(new Dimension(750,600));
cont_vertabla.add(sp_vertabla);
f_vertabla.setContentPane(cont_vertabla);
f_vertabla.pack();
f_vertabla.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//f_vertabla.setResizable(false);
f_vertabla.setVisible(true);
f_vertabla.addWindowListener(this);
}
this is the way the JTable looks
The row listed in the above pic, is the last one in the mysql table
Try adding the line
Vector row = new Vector();
inside the while loop.
I try to create a new table depending on input data and insert it into an docx-document.
Following leads to a corrupted output file:
private Tbl getSampleTable(WordprocessingMLPackage wPMLpackage) {
ObjectFactory factory = Context.getWmlObjectFactory();
int writableWidthTwips = wPMLpackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips();
List<Map<String, String>> data = getSampleTableData();
TableDefinition tableDef = getSampleTableDef();
int cols = tableDef.getColumns().size();
int cellWidthTwips = new Double(Math.floor((writableWidthTwips / cols))).intValue();
Tbl table = TblFactory.createTable((data.size() + 1), cols, cellWidthTwips);
Tr headerRow = (Tr) table.getContent().get(0);
int f = 0;
for (Column column : tableDef.getColumns()) {
Tc column = (Tc) headerRow.getContent().get(f);
f++;
Text text = factory.createText();
text.setValue(column.getName());
R run = factory.createR();
run.getContent().add(text);
column.getContent().add(run);
headerRow.getContent().add(column);
}
int i = 1;
for (Map<String, String> entry : data) {
Tr row = (Tr) table.getContent().get(i);
i++;
int p = 0;
for (String key : entry.keySet()) {
Tc column = (Tc) row.getContent().get(p);
p++;
Text tx = factory.createText();
R run = factory.createR();
tx.setValue(entry.get(key));
run.getContent().add(tx);
column.getContent().add(run);
row.getContent().add(column);
}
}
return table;
}
Without inserting the table the docx-document is created how it shall be.
I use the this function by trying to insert this table in an file that I receive as input parameter:
ByteArrayInputStream bis = new ByteArrayInputStream(file);
WordprocessingMLPackage wPMLpackage = null;
wPMLpackage = WordprocessingMLPackage.load(bis);
// Zip it up
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SaveToZipFile saver = new SaveToZipFile(wPMLpackage);
saver.save(baos);
byte[] template = baos.toByteArray();
WordprocessingMLPackage target = WordprocessingMLPackage.load(new ByteArrayInputStream(template));
target.getMainDocumentPart().getContent().clear();
target.getMainDocumentPart().addObject(getSampleTable(target));
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
SaveToZipFile saver2 = new SaveToZipFile(target);
saver2.save(baos2);
return baos2.toByteArray();
Someone has an idea why the generated file can't be interpreted by Microsoft Word? The error message is "The file can't be opened as its contents causes problems". Manipulation of the document works as long as I don't insert this table.
Inserting the runs in paragraphs leads to the desired result:
private Tbl getSampleTable(WordprocessingMLPackage wPMLpackage) {
ObjectFactory factory = Context.getWmlObjectFactory();
int writableWidthTwips = wPMLpackage.getDocumentModel().getSections()
.get(0).getPageDimensions()
.getWritableWidthTwips();
List<Map<String, String>> data = getSampleTableData();
TableDefinition tableDef = getSampleTableDef();
int cols = tableDef.getColumns().size();
int cellWidthTwips = new Double(
Math.floor((writableWidthTwips / cols))
).intValue();
Tbl table = TblFactory.createTable((data.size() + 1), cols, cellWidthTwips);
Tr headerRow = (Tr) table.getContent().get(0);
int f = 0;
for (Column column : tableDef.getColumns()) {
Tc column = (Tc) headerRow.getContent().get(f);
P columnPara = (P) column.getContent().get(0);
f++;
Text text = factory.createText();
text.setValue(column.getName());
R run = factory.createR();
run.getContent().add(text);
columnPara.getContent().add(run);
}
int i = 1;
for (Map<String, String> entry : data) {
Tr row = (Tr) table.getContent().get(i);
i++;
int d = 0;
for (String key : entry.keySet()) {
Tc column = (Tc) row.getContent().get(d);
P columnPara = (P) column.getContent().get(0);
d++;
Text tx = factory.createText();
R run = factory.createR();
tx.setValue(entry.get(key));
run.getContent().add(tx);
columnPara.getContent().add(run);
}
}
return table;
}
In creating a table (or anything else for that matter), one approach worth bearing in mind is to create what you want in Word, then use one of the docx4j code gen tools to generate corresponding Java code.
The code gen tool is available 2 ways:
online at http://webapp.docx4java.org/OnlineDemo/PartsList.html
or as a Word AddIn, see http://www.docx4java.org/forums/docx4jhelper-addin-f30/
The advantage of the Word AddIn is that you avoid the save-upload cycle.
I used this coding to retrieve the Mysql data to the JTable.but it returns only the first data row of the relevant table of the database but then again it count the number of rows correctly and all it returns is same copy of the first row equal to the row count.
I'm new to Java and netbeans environment so if someone can help me to solve this problem i'll be really grateful and thank you in advance :)
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/data", "root", "1122");
Statement stat = (Statement) con.createStatement();
stat.executeQuery("select * from reserve;");
ResultSet rs=stat.getResultSet();
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
Vector data=new Vector();
Vector columnNames= new Vector();
Vector row = new Vector(columnCount);
for(int i=1;i<=columnCount;i++){
columnNames.addElement(md.getColumnName(i));
}
while(rs.next()){
for(int i=1; i<=columnCount; i++){
row.addElement(rs.getObject(i));
}
data.addElement(row);
}
DefaultTableModel model = new DefaultTableModel(data, columnNames);
jTable1.setModel( model );
You keep adding to the same Vector row. Try creating a new instance for each iteration of rs.next().
You have an error with your Vector. Consider using something like :
Vector data = new Vector(columnCount);
Vector row = new Vector(columnCount);
Vector columnNames = new Vector(columnCount);
for (int i = 1; i <= columnCount; i++) {
columnNames.addElement(md.getColumnName(i));
}
while (rs.next()) {
for (int i = 1; i <= columnCount; i++) {
row.addElement(rs.getObject(i));
}
data.addElement(row);
row = new Vector(columnCount); // Create a new row Vector
}
DefaultTableModel model = new DefaultTableModel(data, columnNames);
jTable1.setModel( model );