convert xls to image - java

I am trying to create multiple and complex Table in PPT (not PPTX), si Im using POI Apache HSLF, The problem is that I have multiple kinds of tables with multiple headers sometimes,
I think then to create my tables on xls files than convert them to image and finally embed them on my generated PPT
I know it is a complex theory, but what I need now is to transform my XLS to image
any help please
Thanks

You cant do it with POI but You can convert or copy charts(graphs) using J XL or Aspose Cells(Aspose is not free).
This is the code snippet to extract excel chart to image
public class ExportChartToImage
{
public static void main(String[] args) throws Exception
{
//Start Excel
Application excelApp = new Application();
excelApp.setVisible(true);
//Create test workbook
Workbook workbook = excelApp.createWorkbook("/home/tejus/Desktop/Chart Test");
//Get the first (and the only) worksheet
final Worksheet worksheet1 = workbook.getWorksheet(1);
//Fill-in the first worksheet with sample data
worksheet1.getCell("A1").setValue("Date");
worksheet1.getCell("A2").setValue("March 1");
worksheet1.getCell("A3").setValue("March 8");
worksheet1.getCell("A4").setValue("March 15");
worksheet1.getCell("B1").setValue("Customer");
worksheet1.getCell("B2").setValue("Smith");
worksheet1.getCell("B3").setValue("Jones");
worksheet1.getCell("B4").setValue("James");
worksheet1.getCell("C1").setValue("Sales");
worksheet1.getCell("C2").setValue("23");
worksheet1.getCell("C3").setValue("17");
worksheet1.getCell("C4").setValue("39");
excelApp.getOleMessageLoop().doInvokeAndWait(new Runnable()
{
public void run()
{
final Variant unspecified = Variant.createUnspecifiedParameter();
final Int32 localeID = new Int32(LocaleID.LOCALE_SYSTEM_DEFAULT);
Range sourceDataNativePeer = worksheet1.getRange("A1:C4").getPeer();
_Worksheet worksheetNativePeer = worksheet1.getPeer();
IDispatch chartObjectDispatch = worksheetNativePeer.chartObjects(unspecified, localeID);
ChartObjectsImpl chartObjects = new ChartObjectsImpl(chartObjectDispatch);
ChartObject chartObject = chartObjects.add(new DoubleFloat(100), new DoubleFloat(150), new DoubleFloat(300), new DoubleFloat(225));
_Chart chart = chartObject.getChart();
chart.setSourceData(sourceDataNativePeer, new Variant(XlRowCol.xlRows));
BStr fileName = new BStr("/home/tejus/Desktop/chart.gif");
Variant filterName = new Variant("gif");
Variant interactive = new Variant(false);
chart.export(fileName, filterName, interactive);
chart.setAutoDelete(false);
chart.release();
chartObject.setAutoDelete(false);
chartObject.release();
chartObjects.setAutoDelete(false);
chartObjects.release();
chartObjectDispatch.setAutoDelete(false);
chartObjectDispatch.release();
}
});
System.out.println("Press 'Enter' to terminate the application");
System.in.read();
//Close the MS Excel application.
boolean saveChanges = false;
workbook.close(saveChanges);
boolean forceQuit = true;
excelApp.close(forceQuit);
}
}
i used J excel

There are 3rd party products like aspose which provides API's for converting worksheets to image file. However you could start by creating a rendering engine which does the geometry layout and write all the data that are available on the sheet to a canvas and then create a converter which gets the pixel data from the canvas and renders to a file.

Related

Apache POI not "Saving" excel file

I am writing a small utility that creates a pivot table in an excel sheet using POI and I want to read the data from the pivot table back to the program which will save it as a PDF file using Itext. I am running into a problem where the program cannot read the data from the pivot table after it is created. The program only can "see" the information in the pivot table after I manually open the created file and hit the save button in excel. Does anyone know a way to read the data from the pivot table from the XSSFPivotTable object or otherwise force a way for the file to "save" so it can be accessed by the program again?
Here is a snippet of code so you can see what I'm talking about. I'm a student so any advice on best practices would be greatly appreciated as well.
public void returnPivotData() throws IOException {
FileInputStream fs = new FileInputStream(this.xlsxFile);
XSSFWorkbook book = new XSSFWorkbook(fs);
XSSFSheet dataSheet = book.getSheet("Sheet1");
AreaReference dataRef = new AreaReference("A1:E15",
SpreadsheetVersion.EXCEL2007);
XSSFPivotTable table = dataSheet.createPivotTable(dataRef,
new CellReference("A16"));
table.addRowLabel(0);
table.addColumnLabel(DataConsolidateFunction.SUM, 3);
// Save the data back to the file
FileOutputStream fsOut = new FileOutputStream(
"D:\\workspace\\test.xlsx");
book.write(fsOut);
fsOut.close();
book.close();
fs.close();
// This does not allow access
FileInputStream fsIn = new FileInputStream("D:\\workspace\\test.xlsx");
XSSFWorkbook bookNew = new XSSFWorkbook(fsIn);
XSSFSheet sheet = bookNew.getSheet("Sheet1");
for (int i = 0; i < 20; i++) {
XSSFRow rowNew = sheet.getRow(i);
XSSFCell cellNew = rowNew.getCell(0,
MissingCellPolicy.CREATE_NULL_AS_BLANK);
System.out.println(cellNew.toString());
}
fsIn.close();
bookNew.close();
}

Changing XLSX form control location with Apache POI

I've some number of xlsm files containing form controls. I'd like to programmatically move a particular button down a few rows on each sheet. My first hope was to do something like this:
FileInputStream inputStream = new FileInputStream(new File("t.xlsm"));
XSSFWorkbook wb = new XSSFWorkbook(inputStream);
XSSFSheet xs = (XSSFSheet)wb.getSheetAt(1);
RelationPart rp = xs.getRelationParts().get(0);
XSSFDrawing drawing = (XSSFDrawing)rp.getDocumentPart();
for(XSSFShape sh : drawing.getShapes()){
XSSFClientAnchor a = (XSSFClientAnchor)sh.getAnchor();
if (sh.getShapeName().equals("Button 2")) {
a.setRow1(a.getRow1()+10);
a.setRow2(a.getRow2()+10);
}
}
However, the shape objects given by XSSFDrawing.getShapes() are copies and any changes to them are not reflected in the document after a wb.write().
I tried a couple other approaches, such as getting the CTShape and parsing the XML within but things quickly got hairy.
Is there a recommended way to manage form controls like this via POI?
I ended up fiddling directly with the XML:
wb = new XSSFWorkbook(new File(xlsmFile));
XSSFSheet s = wb.getSheet("TWO");
XmlObject[] subobj = s.getCTWorksheet().selectPath(declares+
" .//mc:AlternateContent/mc:Choice/main:controls/mc:AlternateContent/mc:Choice/main:control");
String targetButton = "Button 2";
int rowsDown = 10;
for (XmlObject obj : subobj) {
XmlCursor cursor = obj.newCursor();
cursor.push();
String attrName = cursor.getAttributeText(new QName("name"));
if (attrName.equals(targetButton)) {
cursor.selectPath(declares+" .//main:from/xdr:row");
if (!cursor.toNextSelection()) {
throw new Exception();
}
int newRow = Integer.parseInt(cursor.getTextValue()) + rowsDown;
cursor.setTextValue(Integer.toString(newRow));
cursor.pop();
cursor.selectPath(declares+" .//main:to/xdr:row");
if (!cursor.toNextSelection()) {
throw new Exception();
}
newRow = Integer.parseInt(cursor.getTextValue()) + rowsDown;
cursor.setTextValue(Integer.toString(newRow));
}
cursor.dispose();
}
This moves the named button down 10 rows. I had to discover the button name (which may not be easy to do via Excel, I inspected the file directly). I'm guessing this is going to be very sensitive to the version of Excel in use.

convert MS Excel Worksheet to image

Short question
I'm searching a Java library which can convert a worksheet into an image.
My use case
I have a pptx file. That file has on one slide an excel file embedded. In "presentation modus" (I mean when you don't edit the excel), an image representation is shown. That image is generated by PowerPoint and stored in the pptx file in /ppt/images/*.emf. If the data of the excel file gets changed (that's what I do programmatically), the image isn't up to date anymore. So you have to generate a new image of the worksheet and replace the old image by the new one.
Already found Options
convert the excel to pdf with iText and convert the
pdf to an image
Aspose
I wonder if there are alternatives. Any hint is really appreciated.
You can convert your excel file to HTML (e.g. like this) and then convert it to an image (e.g with this library).
Another option is SmartXLS, but it doesen't work in java.awt.headless=true modus and that's a no go for us.
Finally we will do it with aspose.
#spilymp Thanks for the support.
Here is the snipped that will do it just in case that the aspose link won't work anymore:
public void generateImages(final String sourcePath) {
try {
Workbook workbook = new Workbook(sourcePath);
List<Worksheet> worksheets = getAllWorksheets(workbook);
if (worksheets != null) {
int noOfImages = 0;
for (Worksheet worksheet : worksheets) {
if (worksheet.getCells().getCount() > 0 || worksheet.getCharts().getCount() > 0 || worksheet.getPictures().getCount() > 0) {
String imageFilePath = sourcePath + "_output_" + (noOfImages++) + ".jpeg";
SheetRender sr = new SheetRender(worksheet, getImageOrPrintOptions());
sr.toImage(0, imageFilePath);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Returns all worksheets present in given workbook.
*
* #param workbook
* #return all worksheets present in given workbook.
*/
private List<Worksheet> getAllWorksheets(final Workbook workbook) {
List<Worksheet> worksheets = new ArrayList<Worksheet>();
WorksheetCollection worksheetCollection = workbook.getWorksheets();
for (int i = 0; i < worksheetCollection.getCount(); i++) {
worksheets.add(worksheetCollection.get(i));
}
return worksheets;
}
/**
* Returns ImageOrPrintOptions for png images
*
* #return
*/
private ImageOrPrintOptions getImageOrPrintOptions() {
ImageOrPrintOptions imgOptions = new ImageOrPrintOptions();
imgOptions.setImageFormat(ImageFormat.getJpeg());
imgOptions.setOnePagePerSheet(true);
return imgOptions;
}

Set a default cell size while creating an excel document

I am trying to create an excel sheet using Java. I have populated the data into the excel sheet by creating a Workbook object and creating a WritabeSheet object inside it. I want to set a default size to the cell in the WritableSheet object. How do I do that?
Here's the code snippet:
private static void writeDataSheet(WritableSheet s, String str, int i)
throws Exception{
//Format the font
WritableFont wf = new WritableFont(WritableFont.ARIAL,
10, WritableFont.BOLD);
WritableCellFormat cf = new WritableCellFormat(wf);
cf.setWrap(true);
//Create label and write data to one cell of sheet
Label l = new Label(0,i,str,cf);
s.addCell(l);
// I want to set a default size to the columns in the excel sheet here
}
PS: The sheet.autoSizeColumn() does not work for WritableSheet!
Note: I don't work on java & have not used jexcel.
Take a look at this method on WriteableSheet interface
public void setColumnView(int col,
CellView view)
ref: http://jexcelapi.sourceforge.net/resources/javadocs/2_6_10/docs/index.html
Here is how I think, it should work
CellView columnAView = new CellView();
columnAView.setAutoSize(true);
s.setColumnView(1, columnAView);
CellView class reference

Modifying existing excel using jxl

I m not able to edit the existing excel sheet using jxl.
It always creates a new one.
Can anyone please help me out with it.
Please give a small sample code.
jxl is designed for increased read efficiency (since this is the primary use of the API). In order to improve performance, data which relates to output information (eg. all the formatting information such as fonts) is not interpreted when the spreadsheet is read, since this is superfluous when interrogating the raw data values.
However, if we need to modify this spreadsheet a handle to the various write interfaces is needed, which can be obtained using the copy method.
Workbook workbook = Workbook.getWorkbook(new File("myfile.xls"));
WritableWorkbook copy = Workbook.createWorkbook(new File("temp.xls"), workbook);
This copies the information that has already been read in as well as performing the additional processing to interpret the fields that are necessary to for writing spreadsheets. The disadvantage of this read-optimized strategy is that we have two spreadsheets held in memory rather than just one, thus doubling the memory requirements.
But after this, you can do whatever you want. Like:
WritableSheet sheet2 = copy.getSheet(1);
WritableCell cell = sheet2.getWritableCell(1, 2);
if (cell.getType() == CellType.LABEL)
{
Label l = (Label) cell;
l.setString("modified cell");
}
copy.write();
copy.close();
workbook.close();
Note: this is directly taken from Andy Khan's tutorial page.
I know that this is quite an old question, but if anyone will encounter the same problem, then to preserve the correct formatting (font type, colouring, etc. )
you should save the cell format before casting it to Label, and then force the cell to the previous formatting.
Code:
CellFormat cfm = cell.getCellFormat();
Label l = (Label) cell;
l.setString("modified cell");
cell.setCellFormat(cfm);
//there is god example of it, you can copy in ur project and check it out, to
//understand how it works
Workbook wk = Workbook.getWorkbook(new File("ex.xls"));
//
WritableWorkbook wkr = Workbook.createWorkbook(new File("modifed.xls"), wk);
/* second line makes copy of wk excel file object /creates a readable spreadsheet.
both are now similar and i can Modify exiting wkr spreadsheets */
//next 2 line retrieve sheet number 0 and cell (1,1)
WritableSheet getsht = wkr.getSheet(0);
WritableCell getcl = getsht.getWritableCell(1, 1);
//making own font
WritableFont ft = new WritableFont(WritableFont.ARIAL, 20 , WritableFont.BOLD, true , UnderlineStyle.SINGLE);
//making Format, which uses font
WritableCellFormat form = new WritableCellFormat( ft);
Number nb = ( Number ) getcl ;
nb.setCellFormat( form );
wkr.write();
wkr.close();
I personally use this code to append the xls file and create one if it doesn't exist.
Using jxl 2.6:
public class Excel {
private String fileName = "excel_file.xls";
private String sheetName = "sheet1";
private WritableWorkbook writableWorkbook;
private int rowCount;
private Workbook wb;
// assigns checks if file exists or not, both cases we assign it to a WritableWorkbook // object so that we can write to it.
private void assignWorkBook() throws IOException, BiffException {
// File f = new File(System.getProperty("user.dir") +"\\"+fileName);
File inp = new File(fileName);
try{
wb = Workbook.getWorkbook(inp);
writableWorkbook = Workbook.createWorkbook(inp, wb);
} catch (FileNotFoundException e){
writableWorkbook = Workbook.createWorkbook(inp); //Create a new one
}
}
public int getRowCount() {
return rowCount;
}
// this function writes a vector to an excel file, checks if there is already a sheet
// with that name or not, and uses it. then we have to close the Workbook object before
// we could write to the file, and then we save the file.
// That is, the file is always saved after writing to it.
public void writeRow(Vector<String> playerVector) throws WriteException, IOException, BiffException {
assignWorkBook();
WritableSheet excelSheet;
if(writableWorkbook.getNumberOfSheets() == 0) {
excelSheet = writableWorkbook.createSheet(sheetName, 0);
}
else {
excelSheet = writableWorkbook.getSheet(sheetName);
}
rowCount = excelSheet.getRows();
int colCount = 0;
for(String playerStat:playerVector) {
Label label = new Label(colCount++, rowCount, playerStat);
excelSheet.addCell(label);
}
if(wb != null) {
wb.close();
}
writableWorkbook.write();
writableWorkbook.close(); //everytime save it.
}
}

Categories