table not getting created in docx using docx4j library - java

I'm trying to create a table and add it to MainDocumentPart using docx4j library as below but its corrupting the document and it's not opening ( im using MS Word 2010 with docx format )
// creating docx
WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage();
// creating a table
// use ObjectFactory for creating the table, table row and table cell
ObjectFactory factory = Context.getWmlObjectFactory();
// create the table
Tbl table = factory.createTbl();
// create a row
R row = factory.createR();
// create a cell
Tc cell = factory.createTc();
// add the content to cell
cell.getContent().add(wordPackage.getMainDocumentPart().createParagraphOfText("table cell data added"));
// add the cell to row
row.getContent().add(cell);
// add the row to table
table.getContent().add(row);
// adding the table to main document part
wordPackage.getMainDocumentPart().addObject(table);
wordPackage.save(new File("D:\\Programs\\test\\Doc222.docx"));

R is not a row; it is a run.
To generate your table, the easiest way is to create a suitable docx in Microsoft Word (or LibreOffice/OpenOffice or whatever), and upload it to the docx4j demo webapp.

Related

How to add rows to an existing table using Docx4J

I have an existing Workbook with a Sheet that has a table ('table' refers to the Insert Table feature of the Excel UI with column headers and filter arrows, etc). I am having trouble determining which classes to use to edit existing rows of the table or inserting new rows into the table.
I have been successful (thanks in no small part to JasonPlutext) with writing new cell contents to existing cells as well as creating entirely new cells/rows. I'd rather not have to write the header row and all the data rows first and them make it into a table using the API, but I would like to know if anybody know how it should be done. In the past, I could just create the table with the number of rows I knew I would need but in this case the rows quantity is dynamic. I was hoping I could just reference a tablePart and then there would be some method for inserting into a List object.
Any guidance is appreciated.
EDIT:
So as a concrete example, let's say I have a workbook and sheet with an existing table of 2 columns with 2 rows (including the header) starting at A1. I can open the underlying xl>tables>table1.xml and see this:
<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="xr xr3" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" id="5" xr:uid="{FAABA541-34FC-423B-94F5-DDD8D784132E}" name="SummarySFTP" displayName="SummarySFTP" ref="A1:B2" totalsRowShown="0" headerRowDxfId="46" headerRowBorderDxfId="45" tableBorderDxfId="44">
<autoFilter ref="A1:B2" xr:uid="{93499C15-75FB-4436-A9B9-0C1FCBD787F4}">
<filterColumn colId="0" hiddenButton="0"/>
<filterColumn colId="1" hiddenButton="0"/>
</autoFilter>
<tableColumns count="2">
<tableColumn id="1" xr3:uid="{D4DA50CD-C581-4286-9B64-42B02B6646B6}" name="Status"/>
<tableColumn id="2" xr3:uid="{9D4F40B3-B530-42E1-92E9-86D5632CA191}" name="Quantity" dataDxfId="43"/>
</tableColumns>
<tableStyleInfo showFirstColumn="0" showLastColumn="0" showRowStripes="1" showColumnStripes="0"/>
</table>
I can see my two columns, and the ref attribute of the root tag as well as the autoFilter block's ref attribute. What I want to do is add a new row such that the area of the table would be A1:B3.
Inspecting an xlsx file containing a table in the docx4j webapp, it looks fairly straightforward.
It generates code for the contents of the table part like:
CTTable table = smlObjectFactory.createCTTable();
JAXBElement<org.xlsx4j.sml.CTTable> tableWrapped = smlObjectFactory.createTable(table);
// Create object for autoFilter
CTAutoFilter autofilter = smlObjectFactory.createCTAutoFilter();
table.setAutoFilter(autofilter);
autofilter.setRef( "A2:B4");
// Create object for tableColumns
CTTableColumns tablecolumns = smlObjectFactory.createCTTableColumns();
table.setTableColumns(tablecolumns);
tablecolumns.setCount( new Long(2) );
// Create object for tableColumn
CTTableColumn tablecolumn = smlObjectFactory.createCTTableColumn();
tablecolumns.getTableColumn().add( tablecolumn);
tablecolumn.setTotalsRowFunction(org.xlsx4j.sml.STTotalsRowFunction.NONE);
tablecolumn.setName( "Column1");
tablecolumn.setId( 1 );
// Create object for tableColumn
CTTableColumn tablecolumn2 = smlObjectFactory.createCTTableColumn();
tablecolumns.getTableColumn().add( tablecolumn2);
tablecolumn2.setTotalsRowFunction(org.xlsx4j.sml.STTotalsRowFunction.NONE);
tablecolumn2.setName( "Column2");
tablecolumn2.setId( 2 );
// Create object for tableStyleInfo
CTTableStyleInfo tablestyleinfo = smlObjectFactory.createCTTableStyleInfo();
table.setTableStyleInfo(tablestyleinfo);
tablestyleinfo.setName( "TableStyleMedium2");
table.setTableType(org.xlsx4j.sml.STTableType.WORKSHEET);
table.setHeaderRowCount( new Long(1) );
table.setTotalsRowCount( new Long(0) );
table.setName( "Table1");
table.setId( 1 );
table.setRef( "A2:B4");
table.setDisplayName( "Table1");
Once you know the row quantity, you can see you need to write it in 2 places, using setRef and autofilter.setRef

How can i create a single database table in java data from 4 excel sheets?

In my project I have uploaded the excel sheets and I retrieve by using java, after receiving excel files i just want to create a database table.
These excel sheets contains mark list (each excel sheet contain single subject mark list) like student name, internal,external,result.
if it is one excel sheet then i can easily create a table in db. But i have to create a table from 4 sheets.
i just tried to list the each excel files using for loop and get the data from one by one but its not my solution.
STUDENT NAME CIA ESE TOTAL
AJAY G 46 31 77
AJITH V 41 27 68
AJITH KUMAR 40 26 66
And My Java code is here :
String dirs[] = file.list();
for(String i:dirs) {
// here i can get the file one by one
fis = new FileInputStream(fullpath+"/"+i);
wb = WorkbookFactory.create(fis);
System.out.println(wb.getNumberOfSheets());
sh = wb.getSheet("Sheet1");
int noOfRows = sh.getLastRowNum();
int noOfCols = sh.getRow(7).getLastCellNum();
System.out.println("Rows : "+ noOfRows);
System.out.println("Cols : "+ noOfCols);
}
The above is my excel sheet data and all sheets like the same with different subject (Subject name is the file name so i can take it).
What I expect is to create a single table in db like :
Table name : StudentResult
Stuname | Subject1 | Sub1CIA | Sub1ESE | Subject2 | Sub2CIA | Sub2ESE ...
and so on (get remaining excel sheet column like this.)
Assuming each of the sheets contain the column heading, collect the column headings from all the sheets and make a unique set of them. Then you can use this set to create the database table dynamically executing a DDL using JDBC.
If you want to create the table after the for loop, then declare a Set variable above for- loop and keep adding the column headings from each Sheet to it. Once the control is out of for loop you will have the set with column headings. Here is the pseudo code for this
// Declare a set here
Set<String> dbColumns = new HashSet<String>();
String dirs[] = file.list();
for(String i:dirs) {
// For each sheet
// Get the heading row ( may be col 1 depending on the work sheet)
// Get the cells from this row
// Add the values to the dbColumns set
}
// Now dbColumns contains the list for columns to be created
// Iterate through this set and form the DDL Statement
// Execute the DDL using jdbc

Apache POI how to apply Workbook Style to all Pivot Tables. how do i exclude sheets?

So i am working on a program which reads a text file and writes this data in an excel workbook. after the data is written i create pivot tables from the data. to get style in the pivot table i've set the whole workbook style which somewhy only applys to the sheets with the pivot tables and not the data sheets. now i want to exclude one sheet with pivot table from the workbook style. is there a way to exclude one sheet or set the style for the sheets which need it?
code for workbook style:
wb.createDataFormat().putFormat((short) 0, "_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(#_)");
pivot table:
CellReference cr = new CellReference("A1");
CellReference c1 = new CellReference(0, 0);
CellReference c2 = new CellReference(data.getPhysicalNumberOfRows() - 1, data.getRow(0).getLastCellNum() - 1);
AreaReference ar = new AreaReference(c1, c2);
XSSFPivotTable pivotTable = sheet.createPivotTable(ar, cr, data);
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(4).setAxis(STAxis.AXIS_COL);
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(4).addNewItems();
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(4).getItems().addNewItem()
.setT(STItemType.DEFAULT);
pivotTable.getCTPivotTableDefinition().addNewColFields().addNewField().setX(4);
pivotTable.addRowLabel(10);
pivotTable.addRowLabel(11);
pivotTable.addRowLabel(1);
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 0);
i already tried to set the style for the cells in the sheet but didn't work. any suggestions?
so i found an solution here: Apache Poi set data field style for pivot table. this question might also be more accurate on what i wanted to achieve

How to change font color of an existing table cell in Aspose Word in Java?

I have an existing table in Aspose word template, I want to change the font color of the text inside the cell. How can I achieve it?
CellCollection cellList = row.getCells()
def i = 0
Run run;
Cell cell = cellList.get(i)
I am new to Aspose Word.
Please use following code example to change the color of text inside table's cell. Hope this helps you.
//Load the document
Document doc = new Document(MyDir + "in.docx");
//Get the first table in the document
Table table = (Table)doc.getChild(NodeType.TABLE, 0, true);
//Get the first cell of first row
Cell cell = (Cell)table.getRows().get(0).getCells().get(0);
//Change the color of text
for (Run run : (Iterable<Run>)cell.getChildNodes(NodeType.RUN, true))
{
run.getFont().setColor(Color.BLUE);
}
//Save the document
doc.save(MyDir + "Out.docx");
I work with Aspose as Developer evangelist.

Accessing Field Settings of Pivot Table using Apache POI

I am creating a workbook with a sheet populated data from a data source then creating a second sheet with a pivot table view of that data. Everything works fine, but I can't seem to change the default look of the pivot table. I am trying to get the setting ( Row Labels-->Click one from the list-->Field Settings-->Subtotals-->None and Row Labels-->Click one from the list-->Field Settings-->Layout & Print-->'Show item labels in tabular form' ) checked while creating the pivot table but couldn't find the handle / flag in the POI. Tried finding something under pivotTable.getCTPivotTableDefinition() or pivotTable.getCTPivotTableDefinition().getPivotTableStyleInfo(), but no lock. Please advise if there is a way to set these settings using poi during pivot table creation, not after the fact following the steps mentioned in the parenthesis. Here is my pivot table code :
XSSFSheet sheet = (XSSFSheet)wb.createSheet("Data");
...
...
//filling data sheet, skipping this part as it's not relevant
...
XSSFSheet pivotSheet = (XSSFSheet)wb.createSheet("Pivot Table");
AreaReference source = new AreaReference(sheet.getSheetName()+"!A$1:W$"+String.valueOf(sheet.getLastRowNum()));
CellReference position = new CellReference("A3");
XSSFPivotTable pivotTable = pivotSheet.createPivotTable(source, position);
/* Add filters */
pivotTable.addRowLabel(17);
pivotTable.addRowLabel(20);
pivotTable.addRowLabel(21);
pivotTable.addRowLabel(22);
pivotTable.addRowLabel(13);
pivotTable.addRowLabel(19);
pivotTable.addRowLabel(6);
pivotTable.addRowLabel(0);
pivotTable.addRowLabel(18);
pivotTable.addRowLabel(1);
pivotTable.addRowLabel(7);
pivotTable.addRowLabel(9);
Finally figured it out; lack of good documentation forced me to try a zillion things and finally was able to achieve what I wanted; here is the code :
for(CTPivotField ctPivotField:pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldList()){
ctPivotField.setAutoShow(false);
ctPivotField.setOutline(false);
ctPivotField.setSubtotalTop(false);
ctPivotField.setSubtotalCaption("");
}
instead of creating the pivot table every time, I created one template XLS file with all the desired styling and included that in the source, now I am opening that file filling the necessary data in the source tab, and saving the XLS file with the dynamic data with a different name; since the Pivot table tab is marked to refresh when opened, it does the work. Instead of going through the POI API with the limitations on Pivot Tables, creating a template and using it is much easier and flexible if you will generate the same styled pivot table for dynamic data.
#ninjaxelite here how it goes :
List<Object[]> resultSet = //get raw data
XSSFWorkbook wb = null;
try {
wb = new XSSFWorkbook(new FileInputStream(this.getClass().getResource("/content/XLS_template.xlsx").getPath()));
} catch (FileNotFoundException e1) {
//error
} catch (IOException e1) {
//error
}
Map<String, CellStyle> styles = createStyles(wb); // some local function to get styles
XSSFSheet sheet = (XSSFSheet)wb.getSheetAt(0);
XSSFRow row;
XSSFCell cell;
int rowNum = 0;
for (Object[] aRow : resultSet) {
rowNum++;
row = sheet.createRow(rowNum);
cell = row.createCell(0);
cell.setCellValue((String)aRow[0]);
cell.setCellStyle(styles.get("cell_normal_centered"));
...
..
.

Categories