How to get SignatureLines excel apache poi - java

Good morning,
I created an excel with signature lines.
I'm trying to obtain signature lines in a excel document with apache poi library.
XSSFWorkbook w = new XSSFWorkbook(mp.getInputStream());
w.get......?
Any suggestion?
Thanks in advance,
Pablo
I see there is a class called XSSFSignatureLine but i don't see any example to use it.

To get/set a signature line from/into an Excel sheet, apache poi has introduced XSSFSignatureLine in current apache poi 5.x. This class provides a method parse(XSSFSheet sheet) which gets one signature line per sheet. Seems as if apache poihad not expected that there can be multiple signature lines per sheet.
The text data of the signatures are stored in a VML drawing. So if it is only to get the text data out of the signature lines, then one could get the sheet's VML drawing and select the data from that XML. Of course the binary data of the signature lines cannot be got from that XML.
Following code sample shows both nof the methods.
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import java.io.FileInputStream;
class ExcelGetSignatureLines {
static void getSignatureLines(XSSFSheet sheet) throws Exception {
XSSFSignatureLine signatureLine = new XSSFSignatureLine();
signatureLine.parse(sheet);
System.out.println("Found XSSFSignatureLine:");
System.out.println(signatureLine.getSuggestedSigner());
System.out.println(signatureLine.getSuggestedSigner2());
System.out.println(signatureLine.getSuggestedSignerEmail());
}
static void getSignatureLinesFromVMLDrawing(XSSFSheet sheet) throws Exception {
XSSFVMLDrawing vmlDrawing = sheet.getVMLDrawing(false);
if (vmlDrawing != null) {
org.apache.poi.schemas.vmldrawing.XmlDocument vmlDrawingDocument = vmlDrawing.getDocument();
String declareNameSpaces = "declare namespace v='urn:schemas-microsoft-com:vml'; "
+ "declare namespace o='urn:schemas-microsoft-com:office:office' ";
org.apache.xmlbeans.XmlObject[] selectedObjects = vmlDrawingDocument.selectPath(
declareNameSpaces
+ ".//v:shape//o:signatureline");
for (org.apache.xmlbeans.XmlObject object : selectedObjects) {
if (object instanceof com.microsoft.schemas.office.office.CTSignatureLine) {
com.microsoft.schemas.office.office.CTSignatureLine ctSignatureLine = (com.microsoft.schemas.office.office.CTSignatureLine)object;
System.out.println("Found CTSignatureLine:");
System.out.println(ctSignatureLine.getSuggestedsigner());
System.out.println(ctSignatureLine.getSuggestedsigner2());
System.out.println(ctSignatureLine.getSuggestedsigneremail());
}
}
}
}
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("./WorkbookHavingSignatureLines.xlsx"));
for (Sheet sheet : workbook ) {
if (sheet instanceof XSSFSheet) {
System.out.println("Sheet " + sheet.getSheetName());
getSignatureLines((XSSFSheet)sheet);
getSignatureLinesFromVMLDrawing((XSSFSheet)sheet);
}
}
workbook.close();
}
}

Related

How to detect excel cell reference style of a file using apache POI?

I get an excel file through front end and I do not know what is the user preferred cell reference style (A1 or R1C1) for that file. I want to display the header with column position as present in the file.
For example, if the file is using R1C1 reference style then the column position should be shown as 1, 2, 3... and for A1 references, it should return A, B C...
I want to achieve this using Java apache POI. Any lead in this will be helpful.
Thanks in advance.
The used reference mode (either A1 or R1C1) can be stored in the Excel files. It may be omitted. Then Excel defaults to the last used setting in application.
In the old binary *.xls file system (HSSF) it gets stored using a RefModeRecord in the worksheet' s record stream. Although it cannot be different for single worksheets, it will be stored for each worksheet separately. But it cannot be different for different sheets in same workbook.
In Office Open XML file system (*.xlsx, XSSF) it gets stored in xl/workbook.xml using element calcPr having attribute refMode set.
Both is not dicrectly suppoerted by apache poi upto now. But if one knows the internally structure of the file systems, then it can be set and get using following code:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.record.RecordBase;
import org.apache.poi.hssf.record.RefModeRecord;
import org.apache.poi.hssf.model.InternalSheet;
import java.lang.reflect.Field;
import java.util.List;
public class CreateExcelRefModes {
static void setRefMode(HSSFWorkbook hssfWorkbook, String refMode) throws Exception {
for (Sheet sheet : hssfWorkbook) {
HSSFSheet hssfSheet = (HSSFSheet)sheet;
Field _sheet = HSSFSheet.class.getDeclaredField("_sheet");
_sheet.setAccessible(true);
InternalSheet internalsheet = (InternalSheet)_sheet.get(hssfSheet);
Field _records = InternalSheet.class.getDeclaredField("_records");
_records.setAccessible(true);
#SuppressWarnings("unchecked")
List<RecordBase> records = (List<RecordBase>)_records.get(internalsheet);
RefModeRecord refModeRecord = null;
for (RecordBase record : records) {
if (record instanceof RefModeRecord) refModeRecord = (RefModeRecord)record;
}
if ("R1C1".equals(refMode)) {
if (refModeRecord == null) {
refModeRecord = new RefModeRecord();
records.add(records.size() - 1, refModeRecord);
}
refModeRecord.setMode(RefModeRecord.USE_R1C1_MODE);
} else if ("A1".equals(refMode)) {
if (refModeRecord == null) {
refModeRecord = new RefModeRecord();
records.add(records.size() - 1, refModeRecord);
}
refModeRecord.setMode(RefModeRecord.USE_A1_MODE);
}
}
}
static String getRefMode(HSSFWorkbook hssfWorkbook) throws Exception {
for (Sheet sheet : hssfWorkbook) {
HSSFSheet hssfSheet = (HSSFSheet)sheet;
Field _sheet = HSSFSheet.class.getDeclaredField("_sheet");
_sheet.setAccessible(true);
InternalSheet internalsheet = (InternalSheet)_sheet.get(hssfSheet);
Field _records = InternalSheet.class.getDeclaredField("_records");
_records.setAccessible(true);
#SuppressWarnings("unchecked")
List<RecordBase> records = (List<RecordBase>)_records.get(internalsheet);
RefModeRecord refModeRecord = null;
for (RecordBase record : records) {
if (record instanceof RefModeRecord) refModeRecord = (RefModeRecord)record;
}
if (refModeRecord == null) return "not specified";
if (refModeRecord.getMode() == RefModeRecord.USE_R1C1_MODE) return "R1C1";
if (refModeRecord.getMode() == RefModeRecord.USE_A1_MODE) return "A1";
}
return null;
}
static void setRefMode(XSSFWorkbook xssfWorkbook, String refMode) {
if ("R1C1".equals(refMode)) {
if (xssfWorkbook.getCTWorkbook().getCalcPr() == null) xssfWorkbook.getCTWorkbook().addNewCalcPr();
xssfWorkbook.getCTWorkbook().getCalcPr().setRefMode(org.openxmlformats.schemas.spreadsheetml.x2006.main.STRefMode.R_1_C_1);
} else if ("A1".equals(refMode)) {
if (xssfWorkbook.getCTWorkbook().getCalcPr() == null) xssfWorkbook.getCTWorkbook().addNewCalcPr();
xssfWorkbook.getCTWorkbook().getCalcPr().setRefMode(org.openxmlformats.schemas.spreadsheetml.x2006.main.STRefMode.A_1);
}
}
static String getRefMode(XSSFWorkbook xssfWorkbook) {
if (xssfWorkbook.getCTWorkbook().getCalcPr() == null) return "not specified";
if (xssfWorkbook.getCTWorkbook().getCalcPr().getRefMode() == org.openxmlformats.schemas.spreadsheetml.x2006.main.STRefMode.R_1_C_1) return "R1C1";
if (xssfWorkbook.getCTWorkbook().getCalcPr().getRefMode() == org.openxmlformats.schemas.spreadsheetml.x2006.main.STRefMode.A_1) return "A1";
return null;
}
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook(); String filePath = "./CreateExcelRefModes.xlsx";
//Workbook workbook = new HSSFWorkbook(); String filePath = "./CreateExcelRefModes.xls";
Sheet sheet = workbook.createSheet();
if (workbook instanceof XSSFWorkbook) {
XSSFWorkbook xssfWorkbook = (XSSFWorkbook)workbook;
setRefMode(xssfWorkbook, "R1C1" );
//setRefMode(xssfWorkbook, "A1" );
System.out.println(getRefMode(xssfWorkbook));
} else if (workbook instanceof HSSFWorkbook) {
HSSFWorkbook hssfWorkbook = (HSSFWorkbook)workbook;
setRefMode(hssfWorkbook, "R1C1" );
//setRefMode(hssfWorkbook, "A1" );
System.out.println(getRefMode(hssfWorkbook));
}
FileOutputStream out = new FileOutputStream(filePath);
workbook.write(out);
out.close();
workbook.close();
}
}
But question is: Why? Microsoft Excel uses A1 reference mode per default while storing formulas. In stored Excel file systems you never will find R1C1 formulas. Office Open XML stores formulas as strings in XML. And although the Office Open XML specification allows R1C1 there, even Microsoft Excel itself never stores R1C1 formula strings. The old binary *.xls file system stores formulas as binary Ptg records which are independent of their string representation. The conversion to R1C1 is done in Excel GUI only. It is done by the Excel application while parsing the file. Doing this, it puts in memory two kind of formulas each, one A1 and one R1C1. So both kinds of formulas are available in GUI and in VBA.
But apache poi does not support R1C1 formulas until now. If it would must then it would must do the conversion programmatically as the Excel application does. But that code is not public available and not reverse engineered from apache poi up to now.
When using current apache poi versions using reflection will not be necessary anymore. HSSFSheet has a method getSheet which returns the InternalSheet and InternalSheet has a method getRecords which returns the List<RecordBase>.
So code could be changed as so:
...
/*
Field _sheet = HSSFSheet.class.getDeclaredField("_sheet");
_sheet.setAccessible(true);
InternalSheet internalsheet = (InternalSheet)_sheet.get(hssfSheet);
*/
InternalSheet internalsheet = hssfSheet.getSheet();
/*
Field _records = InternalSheet.class.getDeclaredField("_records");
_records.setAccessible(true);
#SuppressWarnings("unchecked")
List<RecordBase> records = (List<RecordBase>)_records.get(internalsheet);
*/
List<RecordBase> records = internalsheet.getRecords();
...

Apache Poi identify formula with reference to another workbook

I have a workbook, which I must clear from all references to other workbooks. I am currently trying to parse the cell formulas wo check if they are referencing any excel file.
For that I use this line
cell.getCellFormula().matches(".*\\[.*\\.xls[xm]?\\].*")
the issue with this is, that the cell looks like this in XML format:
<c r="K64" s="2128">
<f>[5]Segments!$AS$7/Annual!AF38</f>
<v>0.0</v>
</c>
As you can see, the formula doesn't actually contain .xls, '.xlsx' or .xlsm at all. As far as I know [5] indicates a shared string which holds the actual path and therefore the actual value for the formula.
Now one could say and change the regex to .*\\[\d+\\].*, but I think that this can be pretty error prone. Also I think that not literally every external reference will look like this.
So my question is:
How can I identify formulas which reference an external workbook?
If you have any questions, feel free to ask.
EDIT:
I have prepared an sample excel file showcasing the issue. It's available for download at workupload.com
The way shown in Dynamically add External (Cross-Workbook) references definitely is the way to go. Go through all formula tokens and if one of those has an external sheet index, then this formula refers an external sheet.
Example using your uploaded file:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.formula.ptg.*;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
import java.io.FileInputStream;
public class ExcelReadExternalReference {
public static void main(String[] args) throws Exception {
String filePath = "TestExternalLinks.xlsx";
// String filePath = "TestExternalLinks.xls";
Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));
EvaluationWorkbook evalWorkbook = null;
if (workbook instanceof HSSFWorkbook) {
evalWorkbook = HSSFEvaluationWorkbook.create((HSSFWorkbook) workbook);
} else if (workbook instanceof XSSFWorkbook) {
evalWorkbook = XSSFEvaluationWorkbook.create((XSSFWorkbook) workbook);
}
Sheet sheet = workbook.getSheetAt(0);
EvaluationSheet evalSheet = evalWorkbook.getSheet(0);
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.FORMULA) {
String cellFormula = cell.getCellFormula();
System.out.println(cellFormula);
EvaluationCell evaluationCell = evalSheet.getCell(cell.getRowIndex(), cell.getColumnIndex());
Ptg[] formulaTokens = evalWorkbook.getFormulaTokens(evaluationCell);
for (Ptg formulaToken : formulaTokens) {
int externalSheetIndex = -1;
if (formulaToken instanceof Ref3DPtg) {
Ref3DPtg refToken = (Ref3DPtg) formulaToken;
externalSheetIndex = refToken.getExternSheetIndex();
} else if (formulaToken instanceof Area3DPtg) {
Area3DPtg refToken = (Area3DPtg) formulaToken;
externalSheetIndex = refToken.getExternSheetIndex();
} else if (formulaToken instanceof Ref3DPxg) {
Ref3DPxg refToken = (Ref3DPxg) formulaToken;
externalSheetIndex = refToken.getExternalWorkbookNumber();
} else if (formulaToken instanceof Area3DPxg) {
Area3DPxg refToken = (Area3DPxg) formulaToken;
externalSheetIndex = refToken.getExternalWorkbookNumber();
}
if (externalSheetIndex >= 0) {
System.out.print("We have extrenal sheet index: " + externalSheetIndex
+ ". So this formula refers an external sheet in workbook: ");
ExternalSheet externalSheet = null;
if (workbook instanceof HSSFWorkbook) {
externalSheet = evalWorkbook.getExternalSheet(externalSheetIndex);
} else if (workbook instanceof XSSFWorkbook) {
externalSheet = evalWorkbook.getExternalSheet(null, null, externalSheetIndex);
}
String linkedFileName = externalSheet.getWorkbookName();
System.out.println(linkedFileName);
}
}
}
}
}
workbook.close();
}
}

Apache-POI ignoring Excel sheet's rows

I'm using POI 3.11 to read in two Excel files side by side to compare them.
When I cycle through the two files to find the number of rows/columns for each sheet, POI claims no rows for one of the sheets, but if I open one of the files, and make a single edit on a single sheet, and run it through POI again, then the numbers are different.
I wrote a small program to count the rows in a single file before and after I made the change, here's the output:
FileName: clean.xls
Sheet name: [One]
[One] row count: 1
Sheet name: [Two]
[Two] row count: 2
FileName: modified.xls
Sheet name: [One]
[One] row count: 3499
Sheet name: [Two]
[Two] row count: 10
Bear in mind that the change I am making is to sheet One only, and yet the row counts for both sheets seem to be updating. Importantly there are 3499 and 10 rows there respectively on both version of the file.
Here's a cut down version of the code:
package com.jpmc.firmrisk.tools.excel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelFileParser {
private static final Logger LOG = Logger.getLogger(ExcelFileParser.class);
public static void main(String[] args) {
String[] fileNames = new String[] {
"clean.xls",
"modified.xls"
};
for (String fileName: fileNames) {
try {
LOG.info("FileName: " + fileName);
FileInputStream file = new FileInputStream(new File(fileName));
XSSFWorkbook workbook = new XSSFWorkbook(file);
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
XSSFSheet sheet = workbook.getSheetAt(i);
String sheetName = sheet.getSheetName();
LOG.info(" Sheet name: " + sheetName);
int rowCount = 0;
for (Row ignored: sheet) {
rowCount++;
}
LOG.info(" " + sheetName + " row count: " + rowCount);
}
file.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException ae) {
ae.printStackTrace();
}
}
}
}
Rather than using an iterator, I have also tried using the Sheet.getFirstRowNum(), Sheet.getLastRowNum() and Sheet.getPhysicalNumberOfRows() methods, but all claim there is no data on the sheet for the clean spreadsheet.
Has anyone seen this before? And is there a fix for it? OR is this a known problem with Excel files?
It turns out the original sheets were created with SpreadSheet Gears (A C# library apparently) rather than Excel, I'm guessing that POI and SSG have made different assumptions about the structure of an Excel save file, and this is where the problem stems from.

Java Apache POI Excel save as PDF

How can I convert/save excel file to pdf? I'm using java play framework to generate some excel files and now the requirement changes to pdf. I don't want to recode everything.
Is there a way to convert to pdf?
The excel files I'm generating are from a template; I read the excel template file, write changes, and save as new excel file. That way, the template is unchanged. It contains border, image, and other formatting.
You would need the following Java libraries and associated JAR files for the program to work.
POI v3.8
iText v5.3.4
Try this Example to convert XLS to PDF
The complete Java code that accepts Excel spreadsheet data as an input and transforms that to a PDF table data is provided below:
import java.io.FileInputStream;
import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.*;
import java.util.Iterator;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
public class excel2pdf {
public static void main(String[] args) throws Exception{
FileInputStream input_document = new FileInputStream(new File("C:\\excel_to_pdf.xls"));
// Read workbook into HSSFWorkbook
HSSFWorkbook my_xls_workbook = new HSSFWorkbook(input_document);
// Read worksheet into HSSFSheet
HSSFSheet my_worksheet = my_xls_workbook.getSheetAt(0);
// To iterate over the rows
Iterator<Row> rowIterator = my_worksheet.iterator();
//We will create output PDF document objects at this point
Document iText_xls_2_pdf = new Document();
PdfWriter.getInstance(iText_xls_2_pdf, new FileOutputStream("Excel2PDF_Output.pdf"));
iText_xls_2_pdf.open();
//we have two columns in the Excel sheet, so we create a PDF table with two columns
//Note: There are ways to make this dynamic in nature, if you want to.
PdfPTable my_table = new PdfPTable(2);
//We will use the object below to dynamically add new data to the table
PdfPCell table_cell;
//Loop through rows.
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()) {
Cell cell = cellIterator.next(); //Fetch CELL
switch(cell.getCellType()) { //Identify CELL type
//you need to add more code here based on
//your requirement / transformations
case Cell.CELL_TYPE_STRING:
//Push the data from Excel to PDF Cell
table_cell=new PdfPCell(new Phrase(cell.getStringCellValue()));
//feel free to move the code below to suit to your needs
my_table.addCell(table_cell);
break;
}
//next line
}
}
//Finally add the table to PDF document
iText_xls_2_pdf.add(my_table);
iText_xls_2_pdf.close();
//we created our pdf file..
input_document.close(); //close xls
}
}
i hope this will help you
Add on to assylias's answer
The code from assylias above was very helpful to me in solving this problem. The answer from santhosh could be great if you don't care about the resulting PDF looking exactly like your excel pdf export would look. However, if you are, say, filling out an excel template using Apache POI an then trying to export that while preserving its look and not writing a ton of code in iText just to try to get close to that look, then the VBS option is quite nice.
I'll share a Java version of the kotlin assylias has above in case that helps anyone. All credit to assylias for the general form of the solution.
In Java:
try {
//create a temporary file and grab the path for it
Path tempScript = Files.createTempFile("script", ".vbs");
//read all the lines of the .vbs script into memory as a list
//here we pull from the resources of a Gradle build, where the vbs script is stored
System.out.println("Path for vbs script is: '" + Main.class.getResource("xl2pdf.vbs").toString().substring(6) + "'");
List<String> script = Files.readAllLines(Paths.get(Main.class.getResource("xl2pdf.vbs").toString().substring(6)));
// append test.xlsm for file name. savePath was passed to this function
String templateFile = savePath + "\\test.xlsm";
templateFile = templateFile.replace("\\", "\\\\");
String pdfFile = savePath + "\\test.pdf";
pdfFile = pdfFile.replace("\\", "\\\\");
System.out.println("templateFile is: " + templateFile);
System.out.println("pdfFile is: " + pdfFile);
//replace the placeholders in the vbs script with the chosen file paths
for (int i = 0; i < script.size(); i++) {
script.set(i, script.get(i).replaceAll("XL_FILE", templateFile));
script.set(i, script.get(i).replaceAll("PDF_FILE", pdfFile));
System.out.println("Line " + i + " is: " + script.get(i));
}
//write the modified code to the temporary script
Files.write(tempScript, script);
//create a processBuilder for starting an operating system process
ProcessBuilder pb = new ProcessBuilder("wscript", tempScript.toString());
//start the process on the operating system
Process process = pb.start();
//tell the process how long to wait for timeout
Boolean success = process.waitFor(timeout, minutes);
if(!success) {
System.out.println("Error: Could not print PDF within " + timeout + minutes);
} else {
System.out.println("Process to run visual basic script for pdf conversion succeeded.");
}
} catch (Exception e) {
e.printStackTrace();
Alert saveAsPdfAlert = new Alert(AlertType.ERROR);
saveAsPdfAlert.setTitle("ERROR: Error converting to pdf.");
saveAsPdfAlert.setHeaderText("Exception message is:");
saveAsPdfAlert.setContentText(e.getMessage());
saveAsPdfAlert.showAndWait();
}
VBS:
Option Explicit
Dim objExcel, strExcelPath, objSheet
strExcelPath = "XL_FILE"
Set objExcel = CreateObject("Excel.Application")
objExcel.WorkBooks.Open strExcelPath
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)
objSheet.ExportAsFixedFormat 0, "PDF_FILE",0, 1, 0, , , 0
objExcel.ActiveWorkbook.Close
objExcel.Application.Quit
An alternative is to use a VB script and call it from Java.
Example:
xl2pdf.vbs
Option Explicit
Dim objExcel, strExcelPath, objSheet
strExcelPath = "$XL_FILE"
Set objExcel = CreateObject("Excel.Application")
objExcel.WorkBooks.Open strExcelPath
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)
objSheet.ExportAsFixedFormat 0, "$PDF_FILE",0, 1, 0, , , 0
objExcel.ActiveWorkbook.Close
objExcel.Application.Quit
In Java (actually kotlin, but easy to translate)
fun xl2pdf(xlFile: Path, pdfFile: Path, timeout: Long = 1, timeUnit: TimeUnit = TimeUnit.MINUTES) {
val tempScript = Files.createTempFile("script", ".vbs")
val script = Files.readAllLines(Paths.get("xl2pdf.vbs"))
.map { it.replace("\$XL_FILE", "$xlFile") }
.map { it.replace("\$PDF_FILE", "$pdfFile") }
Files.write(tempScript, script)
try {
val pb = ProcessBuilder("wscript", tempScript.toString())
val process = pb.start()
val success = process.waitFor(timeout, timeUnit)
if (!success) LOG.error("Could not print PDF within $timeout $timeUnit")
} catch (e: IOException) {
LOG.error("Error while printing Excel file to PDF", e)
}
}
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>http://repo.e-iceblue.com/nexus/content/groups/public/</url>
</repository>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.xls.free</artifactId>
<version>5.1.0</version>
</dependency>
import com.spire.xls.FileFormat;
import com.spire.xls.Workbook;
import java.io.File;
public class EIceblueConverter {
public static void main(String[] args) {
for (Sources xls : Sources.values()) {
if (isFileExists(xls)) convert(xls);
}
}
private static boolean isFileExists(Sources xls) {
File file = new File(xls.getPath());
return file.exists() && file.isFile();
}
private static void convert(Sources xls) {
Workbook workbook = new Workbook();
workbook.loadFromFile(xls.getPath());
workbook.getConverterSetting().setSheetFitToPage(true);
workbook.saveToFile(Util.getOutputPath(xls.getPath()), FileFormat.PDF);
}
}
Before converting you should edit view area in file.xls*
... and more convertors, including the interesting solution: use libre office as converter .xls* to .pdf.
(do test it in src/main/java/jodconverter/AppStarter.java)
https://github.com/fedor83/xlsToPdfConverter.git
Here is the full fledge working example
Dependencies :
compile 'com.itextpdf:itextpdf:5.5.13.2'
compile 'org.apache.poi:poi-ooxml:5.0.0'
Java code:
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import java.util.Iterator;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
public class Excel2PDF {
public static void main(String[] args) throws Exception {
Workbook my_xls_workbook = WorkbookFactory.create(new File("/Users/harshad/Desktop/excel.xlsx"));
Sheet my_worksheet = my_xls_workbook.getSheetAt(0);
short availableColumns = my_worksheet.getRow(0).getLastCellNum();
System.out.println("Available columns : " + availableColumns);
Iterator<Row> rowIterator = my_worksheet.iterator();
Document iText_xls_2_pdf = new Document();
PdfWriter.getInstance(iText_xls_2_pdf, new FileOutputStream("/Users/harshad/Desktop/excel.pdf"));
iText_xls_2_pdf.open();
PdfPTable my_table = new PdfPTable(availableColumns);
PdfPCell table_cell = null;
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
default:
try {
table_cell = new PdfPCell(new Phrase(cell.getStringCellValue()));
} catch (IllegalStateException illegalStateException) {
//TODO: Need to handle exceptions for different type too
if (illegalStateException.getMessage().equals("Cannot get a STRING value from a NUMERIC cell")) {
table_cell = new PdfPCell(new Phrase(String.valueOf(cell.getNumericCellValue())));
}
}
my_table.addCell(table_cell);
break;
}
}
}
iText_xls_2_pdf.add(my_table);
iText_xls_2_pdf.close();
my_xls_workbook.close();
}
}

How to read and write values in excel using java?

Sample Excel --> Sorry I'm not allowed to attached a image..
TC No. | Title | Result
1 | State and Vin | Failed
2 | State and Reg Code | Passed
3 | Booking a Test Drive | Passed
public class sampleTest{
public static void main(String[] args) throws Exception {
int iTest = 2, iTest2 = 3;
if (iTest == iTest2){
//It will pass a value into the excel (e.g. "Passed")
}
else{
//It will pass a value into the excel (e.g. "Failed")
}
}
My program's goal is to generate a report by getting the Passed and Failed results from my tests. My main problem here is on how to read the results from the excel and place the value "Passed" or "Failed" under Result column.
Download the apache poi jar from here
Go through these examples which demonstrates how to read/write xls data from a java program
Sample help code:
public static void main(String[] args) throws IOException {
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("sheet");
Row row = sheet.createRow((short) 0);
row.createCell(0).setCellValue(1.2);
row.createCell(1).setCellValue(wb.getCreationHelper().createRichTextString("This is a string"));
row.createCell(2).setCellValue(true);
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
}
This might help you to get started.
The whole flow is:
Create a workbook => The main xls file
Then create a sheet
Then create a row.
For each row create as many cells as you want and fill the cells with different values
Write the workbook like a file.
There can be multiple type of cells see this for more info.
To know how to read an excel file:
InputStream myxls = new FileInputStream("workbook.xls");
wb = new HSSFWorkbook(myxls);
sheet = wb.getSheetAt(0); // first sheet
row = sheet.getRow(0); // third row
HSSFCell cell = (HSSFCell) row.getCell((short)1); // fourth cell
if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
System.out.println("The Cell was a String with value \" " + cell.getStringCellValue()+" \" ");
} else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
System.out.println("The cell was a number " + cell.getNumericCellValue());
} else {
System.out.println("The cell was nothing we're interested in");
}
For more info see this
Via library that will be your interface to Excel document. One option is Apache POI. Excel example code can be found from here.
Other option is Java Excel API.

Categories