I am working on Apache POI to extract data from MSEcxel files. What I need to do is to combine selective rows into a single string and generate QR code and further generate a word document and put this data (both generated string and QR code) into two columns of a table. What I need to get is to skip rows which don't fit to the required information.
I am using Apache POI to read excel files as follows
private Workbook workbook;
if(filePath.endsWith(".xls")) {
workbook = new HSSFWorkbook(excelInputFile)
} else if(filePath.endsWith(".xlsx")) {
workbook = new XSSFWorkbook(excelInputFile);
}
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> excelRowIterator = sheet.iterator();
List<String> outputHeadings = new ArrayList<>();
outputHeadings.add("Data"); outputHeadings.add("QR Code");
int j = 0;
XWPFTable tab = document.createTable();
XWPFTableRow wordTableRow = tab.getRow(j); // First row
wordTableRow.getCell(0).setText(outputHeadings.get(0));
wordTableRow.addNewTableCell().setText(outputHeadings.get(1));
List<String> excelFileHeadings = new ArrayList<>();
Row heading = excelRowIterator.next();
Iterator<Cell> headingIterator = heading.cellIterator();
excelFileHeadings.clear();
boolean qrCodeFormat = false;
int k = 0, qrCodeCellNo = 0;
while(headingIterator.hasNext()) {
Cell cellHeader = headingIterator.next();
String headerText = cellHeader.getStringCellValue();
if(headerText.equals("QR Code")) {
qrCodeFormat = true;
qrCodeCellNo = k;
}
excelFileHeadings.add(headerText);
k++;
}
if(!qrCodeFormat) {
throw new IOException("The file has not been formatted! Please format the file properly and then proceed.");
}
while (excelRowIterator.hasNext()) {
Row inputDataRow = excelRowIterator.next();
Iterator<Cell> cellIterator = inputDataRow.cellIterator();
String excelRow = "";
int i = 0;
boolean generateQRCodeForThisRow = false;
String cellText = "";
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
CellType cellType = cell.getCellType();
switch (cellType) {
case NUMERIC:
cellText = excelFileHeadings.get(i++) + ": " + (int)cell.getNumericCellValue();
excelRow += cellText + "\r\n ";
tableText(wordTableRow.getCell(0).getParagraphs(), cellText);
break;
case STRING:
cellText = cell.getStringCellValue();
if(i == qrCodeCellNo) {
i ++;
if(cellText.equals("yes")) {
generateQRCodeForThisRow = true;
wordTableRow = tab.createRow(); // First row
}
continue;
}
cellText = excelFileHeadings.get(i++) + ": " + cell.getStringCellValue();
excelRow += cellText + "\r\n";
tableText(wordTableRow.getCell(0).getParagraphs(), cellText);
break;
default:
break;
}
}
System.out.println(excelRow);
if(generateQRCodeForThisRow) {
XWPFParagraph paragraph = wordTableRow.getCell(1).addParagraph();
XWPFRun run = paragraph.createRun();
generateQRcode(excelRow, charset, 100, 100, run);
}
j++;
}
// Closing file output streams
document.write(wordOutputFile);
private static void tableText(List<XWPFParagraph> paragraph, String text) {
XWPFRun run = paragraph.get(0).createRun();
run.setFontSize(14);
run.setFontFamily("Times New Roman");
run.setText(text);
run.addBreak();
}
public static void generateQRcode(String data, String charset,
int h, int w, XWPFRun run) throws WriterException, IOException, InvalidFormatException {
BitMatrix matrix = new MultiFormatWriter().encode(
new String(data.getBytes(charset), charset),
BarcodeFormat.QR_CODE, w, h);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(matrix, "png", baos);
byte[] dataBytes = baos.toByteArray();
ByteArrayInputStream inStreambj = new ByteArrayInputStream(dataBytes);
BufferedImage newImage = ImageIO.read(inStreambj);
ImageIO.write(newImage, "png", new File("temp.png") );
FileInputStream fis = new FileInputStream("temp.png");
run.addPicture(fis, XWPFDocument.PICTURE_TYPE_JPEG, "temp",
Units.toEMU(w), Units.toEMU(h));
baos.close();
inStreambj.close();
fis.close();
}
I have manually put a cell in name QR Code and put a value yes under all the rows which I want to process and get their QR code. This way I am getting the job done. But I want to generalize it by giving some intelligence to it. I need to get rid of the QR Code column with "yes" written as a value.
Any help in this regard will be highly appreciated.
Thank you