Java - Read excel, modify then save to a new file - java

I have it currently working so that my application is generating the content, then saving the information into an excel file, this is working as expected using the below code
public void writeExcel(ClassManager cm, String fn, ErrorManager em) throws FileNotFoundException, IOException {
// Get classes
classes = cm.getClasses();
String fileName = (!"".equals(fn)) ? fn : "temp.xlsx";
// Create Rows
setupRows();
File currDir = new File(".");
String path = currDir.getAbsolutePath();
String fileLocation = path.substring(0, path.length() - 1) + fileName;
FileOutputStream outputStream = new FileOutputStream(fileLocation);
workbook.write(outputStream);
outputStream.close();
workbook.close();
}
the setupRow function calls several other functions, all setup the same as below
public void setupRowTemplateName() {
int start = 2;
Row row = sheet.createRow(1);
for (int i = 0; i < classes.size(); i++) {
// Get class and template details
Classes c = classes.get(i);
Template t = c.getTemplate();
// Create cell
Cell cell = row.createCell(start);
// Set contents
if(t != null) {
cell.setCellValue(t.getName());
}
start++;
}
}
I'm trying to adjust the saving so that it takes an excel file, adds the information to that, then saves as a new file (i.e: Take file "Codes Template.xlsx", add data, save as another filename.
So far I have
public void writeExcelReplace(ClassManager cm, String fn, ErrorManager em) throws FileNotFoundException, IOException {
File currDir = new File(".");
String path = currDir.getAbsolutePath();
String fileLocationOpen = path.substring(0, path.length() - 1) + "Codes Template.xlsx";
FileInputStream inputStream = new FileInputStream(new File(fileLocationOpen));
workbook = WorkbookFactory.create(inputStream);
sheet = workbook.getSheetAt(0);
// Get classes
classes = cm.getClasses();
String fileName = (!"".equals(fn)) ? fn : "temp.xlsx";
// Create Rows
setupRows();
String fileLocation = path.substring(0, path.length() - 1) + fileName;
inputStream.close();
FileOutputStream outputStream = new FileOutputStream(fileLocation);
workbook.write(outputStream);
outputStream.close();
workbook.close();
}
This is taking the content from the "template" file and saving it to the new file, but none of the content from setupRows is being added

Related

How can I put 2 ByteArrayOutputStreams into a zip file for download?

I was trying to generate 2 PDF data and put it inside a ZIP file for download (through response.getOutputStream) but I don't have idea how to do it properly:
public void export() {
String fileName = "B2B_Price_List.zip";
String fileNameUSD = "B2B_Price_List_USD.pdf";
String fileNameEU = "B2B_Price_List_EU.pdf";
String contentTypePDF = "application/pdf";
String[] headerPDF = new String[2];
headerPDF[0] = "Content-disposition";
headerPDF[1] = "attachment; filename=\"" + fileNameUSD + "\"";
headerPDF[2] = "attachment; filename=\"" + fileNameEU + "\"";
String contentTypeZIP = "application/zip";
String[] headerZIP = new String[1];
headerZIP[0] = "Content-disposition";
headerZIP[1] = "attachment; filename=\"" + fileName + "\"";
ByteArrayOutputStream outUSD = new ByteArrayOutputStream();
outUSD = CSVHandler.downloadPriceListPDF(outUSD, fileNameUSD, ListToPDFMap(productsUSD), true);
ByteArrayOutputStream outEU = new ByteArrayOutputStream();
outEU = CSVHandler.downloadPriceListPDF(outEU, fileNameEU, ListToPDFMap(productsEU), false);
// ZIP CODING GOES HERE
}
This function returns ByteArrayOutputStream to be used later:
public static ByteArrayOutputStream downloadPriceListPDF
(ByteArrayOutputStream output, final String filename,
Map<String, Map<String, List<B2BProductData>>> datas,
boolean amerCustomer) {
try {
PdfDocument pdfDoc = null;
try {
pdfDoc = new PdfDocument(new PdfWriter(output));
PageSize pageSize = new PageSize(PageSize.A4);
Document doc = new Document(pdfDoc, pageSize, false);
PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage());
String coverImage = COVER_IMAGE;
if(!amerCustomer) {
coverImage = COVER_IMAGE_1;
}
canvas.addImage(ImageDataFactory.create(CSVHandler.class.getClassLoader().getResource(coverImage).getPath()), pageSize, false);
// loop thru category
int pageNo = 2;
Map<String, List<B2BProductData>> inputDatas = new LinkedHashMap<>();
for(String category : datas.keySet()) {
Map<String, List<B2BProductData>> prods = datas.get(category);
while(true) {
inputDatas = new LinkedHashMap<>();
Map<String, List<B2BProductData>> remaindatas = filterDatas(inputDatas, prods);
if(inputDatas.size() > 0) {
createPDFPage(pdfDoc, doc, category, inputDatas, pageNo ++, amerCustomer);
}
if(remaindatas.size() > 0) {
prods = remaindatas;
} else {
break;
}
}
}
doc.close();
return output;
} catch (IOException e) {
LOG.error(e.getMessage());
return output;
}
}
catch (final Exception ex) {
LOG.error("Export Products got error: " + ex.getMessage());
return output;
}
}
I made it like this:
Declared the Filenames to be used later.
String fileName = "B2B_Price_List.zip";
String fileNameUSD = "B2B_Price_List_USD.pdf";
String fileNameEU = "B2B_Price_List_EU.pdf";
Declare a new ByteArrawOutputStream class and initialize with "new".
ByteArrayOutputStream outUSD = new ByteArrayOutputStream();
ByteArrayOutputStream outEU = new ByteArrayOutputStream();
After generating a PDF file, return the value ByteArrayOutputStream and assign to the ByteArrayStream declared earlier.
if (hasUSD) outUSD = CSVHandler.generatePriceListPDF(outUSD, ListToPDFMap(productsUSD), true, true);
if (hasEU) outEU = CSVHandler.generatePriceListPDF(outEU, ListToPDFMap(productsEU), false, true);
Declare an outputstream to be used to hold response object's OutputStream.
OutputStream responseOutputStream;
Declare the header strings to be assigned to the response object's header data. In this case the MIME type would be application/zip for zip file. The fileName (B2B_Price_List.zip) is also used to define the download's filename.
String contentTypeZIP = "application/zip";
String[] headerZIP = new String[1];
headerZIP[0] = "Content-disposition";
headerZIP[1] = "attachment; filename=\"" + fileName + "\"";
Set the response object's headers.
response.setContentType(contentTypeZIP);
response.setHeader(headerZIP[0], headerZIP[1]);
Set the responseOutputStream to hold the response object's outputstream.
responseOutputStream = response.getOutputStream();
Declare a ZipOutputStream and initialize new with the response's outputstream as a parameter. The parameter will be used to write to write here the file to be downloaded later, in this case, the ZIP file.
ZipOutputStream zos = new ZipOutputStream(responseOutputStream);
Declare the ZipEntry objects to be put inside the ZIP file. Initialize new with the filename string as a parameter. In this case, we'll put 2 files inside the ZIP file for example.
ZipEntry zipEntryUSD = new ZipEntry(fileNameUSD);
ZipEntry zipEntryEU = new ZipEntry(fileNameEU);
Put each entries (or files) one at a time, after the putNextEntry is called for an entry, it is then assumed that the next .write called will be written to the previously put entry.
In this case we called the .write with the ByteArrayOutputStream.toByteArray() to convert to ByteArray as a parameter. Don't forget to close the entry by calling .closeEntry(), then proceed to the next file(s) with the same procedure earlier.
zos.putNextEntry(zipEntryUSD);
zos.write(outUSD.toByteArray());
zos.closeEntry();
zos.putNextEntry(zipEntryEU);
zos.write(outEU.toByteArray());
zos.closeEntry();
After writing the entries (files) you needed inside the ZIP, don't forget to close the ZipOutputStream (zos in this case).
zos.close();
The file will then proceed for download after you flush / close the response's output stream. You may ignore flush but to be sure, I included it anyway.
responseOutputStream.flush();
responseOutputStream.close();
END OF CODE BLOCK
CSVHandler.generatePriceListPDF
Now this is the function used to generate PDF > to > ByteArrayOutputStream. We passed the output object ByteArrayOutputStream from earlier to be re-assigned to the passed ByteArrayOutputStream object outside this function.
example:
outUSD = CSVHandler.generatePriceListPDF(outUSD, ListToPDFMap(productsUSD), true, true);
FUNCTION BLOCK START
public static ByteArrayOutputStream downloadPriceListPDF
(ByteArrayOutputStream output, final String filename,
Map<String, Map<String, List<B2BProductData>>> datas,
boolean amerCustomer, boolean autoCloseByteArrayOutputStream) {
try {
PdfDocument pdfDoc = null;
try {
Initialize writer as new PdfWriter with the ByteArrayOutputStream as a parameter, in this case the output object from the function parameter.
PdfWriter writer = new PdfWriter(output);
Initialize pdfDoc as new PdfDocument with the PdfWriter object writer in this case as parameter. This instructs the pdfDoc to write directly to the ByteArrayOutputStream (output) object
pdfDoc = new PdfDocument(writer);
Initialize PDF document parameters such as sizes and such.
PageSize pageSize = new PageSize(PageSize.A4);
Document doc = new Document(pdfDoc, pageSize, false);
PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage());
This is the part where you write your PDF, with data, images or anything up to you.
// YOUR OWN PDF WRITE OPERATION HERE
Don't forget to close your PDF Document after you finish writing stuff.
doc.close();
The function parameter autoCloseByteArrayOutputStream boolean I added determines if you want to close the ByteArrayOutputStream inside this function, or close it outside if you want to supplement the content outside. Your choice, but don't forget to close ByteArrayOutputStream all the time anyway.
If (autoCloseByteArrayOutputStream) {
output.flush();
output.close();
}
Return the output ByteArrayOutputStream.
return output;
} catch (IOException e) {
If an exception occur, it's important to return an object on all code paths. In this case we return a null value ByteArrayOutputStream in an event of error.
LOG.error(e.getMessage());
return output;
}
}
catch (final Exception ex) {
Same here, errors return null ByteArrayOutputStream in case of error.
LOG.error("Export Products got error: " + ex.getMessage());
return output;
}
}
END OF FUNCTION BLOCK

how to upload single excel doc with multiple sheets to a multiple table using java

i am trying to upload a excel document with multiple sheets
e.g file name: payroll that contains
sheet 0
sheet 1 and etc....
and i have a multiple database table like table 1, table 2 and etc.....
Now i am trying for map sheet 0 to table 1
sheet 1 for table 2 and etc using java
i am already using single sheet to one table
e.g code:
/**
*
*/
private static final long serialVersionUID = 1L;
public File file;
private int totalRecords=0;
private int successRecords=0;
private int failureRecords=0;
private String totalMsg="Total No. of records processed :";
private String successMsg="No. of records succeeded :";
private String failureMsg="No. of records failed:";
#SuppressWarnings("deprecation")
public OutputStream receiveUpload(String filename, String mimeType) {
// Create upload stream
FileOutputStream fos = null; // Output stream to write to
try {
// Open the file for writing.
file = new File("" + filename);
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
UI.getCurrent().showNotification(
"Could not open file<br/>", e.getMessage(),
Notification.TYPE_ERROR_MESSAGE);
return null;
}
return fos; // Return the output stream to write to
}
public void uploadSucceeded(SucceededEvent event) {
// Show the uploaded file in the image viewer
try{
Session session = com.systems.payrolladmin.PayrolladminMainUI.sf.openSession();
session.beginTransaction();
//File excel = new File(FILE_PATH);
FileInputStream fis = new FileInputStream(file);
#SuppressWarnings("resource")
XSSFWorkbook book = new XSSFWorkbook(fis);
XSSFSheet sheet = book.getSheetAt(0);
Row row;
ArrayList<Resignee> ErrorDataList2 = new ArrayList<Resignee>();
int LastRowNum=sheet.getLastRowNum();
for(int i=1; i<=LastRowNum; i++){
row = sheet.getRow(i);
String vempId1 = row.getCell(1).getStringCellValue();
Date vdor1=row.getCell(3).getDateCellValue();
Date vdorr=row.getCell(4).getDateCellValue();
String vRemark = row.getCell(5).getStringCellValue();
int a=5;
int b=5;
if(a==b)
{
Resignee resobj = new Resignee();
resobj.setEmpId(vempId1);
resobj.setDOR(vdor1);
resobj.setDOReliv(vdorr);
resobj.setRemarks(vRemark);
session.save(resobj);
resobj=null;
successRecords++;
}else{
Resignee error = new Resignee();
error.setEmpId(vempId1);
error.setDOR(vdor1);
error.setDOReliv(vdorr);
error.setRemarks(vRemark);
error.setRemarks(vRemark);
ErrorDataList2.add(error);
error=null;
failureRecords++;
}
totalRecords++;
}
session.getTransaction().commit();
session.close();
fis.close();
//write to excel
#SuppressWarnings("resource")
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet spreadsheet = workbook.createSheet("employe db");
XSSFRow xrow=spreadsheet.createRow(0);
XSSFCell cell;
cell=xrow.createCell(0);
cell.setCellValue("EMPLOYEE ID");
cell=xrow.createCell(1);
cell.setCellValue("DOR");
cell=xrow.createCell(2);
cell.setCellValue("DORELIEVE");
cell=xrow.createCell(3);
cell.setCellValue("REMARKS");
int i=1;
for (Resignee nobj : ErrorDataList2) {
xrow=spreadsheet.createRow(i);
cell=xrow.createCell(0);
cell.setCellValue(nobj.getEmpId());
cell=xrow.createCell(1);
cell.setCellValue(nobj.getDOR());
cell=xrow.createCell(2);
cell.setCellValue(nobj.getDOReliv());
cell=xrow.createCell(3);
cell.setCellValue(nobj.getRemarks());
i++;
}
FileOutputStream out = new FileOutputStream(
new File("F:\\Error Excel\\ResingeeError.xlsx"));
workbook.write(out);
out.close();
Your question makes it sound like your code is working for a single sheet. If that is true, then the line that gets the first sheet,
XSSFSheet sheet = book.getSheetAt(0);
can be updated to look at multiple sheets as shown in this question Use
book.getNumberOfSheets();
to get the number of sheets in the workbook and then process each separately was you are already doing with sheet 0

How can close PDF file if it is open?

I can create a PDF file with iText library in Java. This works, but now I have this problem, I execute the method, then I have a PDF file, its name is file.pdf and it is ok. Now I re-call the function to create the PDF file, its name is file.pdf but now, if the file is just open, I have an error.
FileNotFoundException:Impossible to access at file
And is ok this, so I want that if the file is open, from code, close the file then recreate the file and open it.
This is my code to create a PDF file:
public static void printFile(String nomeFolder, String nomeFile,List<Articoli> listaArticoli, boolean aprire)throws DocumentException{
String folderName = DateUtil.getDataGiornaliera();
nomeFolder = (new StringBuilder()).append(nomeFolder).append(nomeFile+"_"+folderName).append(".pdf").toString();
File f = new File(nomeFolder);
try {
OutputStream os = new FileOutputStream(f);
Document doc = new Document(PageSize.A4.rotate(), -65F, -65F, 85F, 40F);
PdfWriter docWriter = PdfWriter.getInstance(doc, os);
EndPageFoglioFatturaFatt hp2 = new EndPageFoglioFatturaFatt(nomeFolder, "Img/ineco1.jpg",folderName);
docWriter.setPageEvent(hp2);
FooterDocumenti hp = new FooterDocumenti(nomeFolder, "Img/ineco1.jpg",folderName);
docWriter.setPageEvent(hp);
doc.open();
float[] colonne = {0.7f,1.5f,4.5f,0.5f,0.5f,1.5f,1.5f,1.5f};
PdfPTable table = new PdfPTable(colonne);
table.setHeaderRows(1);
String[] intestazioni = {"C.ART","C.BARRE", "NOME ARTICOLO","IVA(%)", "Q.TA",
"PR.VENDITA", "ULT.PR.VENDITA", "ULT.DATA ACQUISTO"};
PdfPCell cell = new PdfPCell();
for(int i = 0; i< intestazioni.length; i++){
cell = new PdfPCell(new Paragraph(intestazioni[i], FontFactory.getFont("Century Gothic", 8F)));
cell.setGrayFill(0.9F);
cell.setUseAscender(true);
cell.setHorizontalAlignment(1);
cell.setVerticalAlignment(5);
cell.setBorderWidth(0.5F);
cell.setFixedHeight(15F);
table.addCell(cell);
}
//Vector v = db.eseguiQueryTuttiArticoli("SELECT ARTICOLIDETT.CodArticolo,NomeArticolo,Iva, Quantita,PrezzoAttuale, PrezzoRivenditore, PrezzoIngrosso, Soglia FROM Articolidett,Articoliquantita WHERE ARTICOLIDETT.CODARTICOLO = ARTICOLIQUANTITA.CODARTICOLO ORDER BY NOMEARTICOLO");
for (Articoli articoli : listaArticoli) {
cell = new PdfPCell(new Paragraph(articoli.getCodArticoloString(), FontFactory.getFont("Century Gothic", 10F)));
cell.setVerticalAlignment(5);
cell.setHorizontalAlignment(0);
cell.setColspan(0);
cell.setBorderWidth(0.5F);
table.addCell(cell);
....
....
CODE TO BUILD A FILE
.....
.....
}
doc.add(table);
doc.close();
os.close();
} catch (FileNotFoundException e) {
log.logStackTrace(e);
VisualMessageStampe.getErroreFileAperto();
}
catch(IOException exp)
{
log.logStackTrace(exp);
}
catch(DocumentException exp2)
{
log.logStackTrace(exp2);
}
if(aprire)
{
if(Desktop.isDesktopSupported())
{
try
{
Desktop.getDesktop().open(f.getCanonicalFile());
}
catch(IOException ex)
{
log.logStackTrace(ex);
}
} else
{
VisualMessageStampe.getErroreAcrobatInesistente();
}
}
}
How can I fixed my problem?
You cannot open an OutputStream into a file opened in external application (Adobe Reader or stuff). Some things you could do instead:
Create new filename for each iteration (creating tempfiles is cheap)
Check if file exists before you go and overwrite. If exists create a suffix (_1, _2, ...) and check that does not exist.
Alert user once you see that message to "please close PDF file before creating new"
Something like this might help:
protected File getFile(String nomeFile, String nomeFolder) {
String folderName = DateUtil.getDataGiornaliera();
nomeFolder = (new StringBuilder()).append(nomeFolder).append(nomeFile+"_"+folderName).append(".pdf").toString();
File f = new File(nomeFolder);
int suffix = 1;
while(f.exists()) {
nomeFolder = (new StringBuilder()).append(nomeFolder).append(nomeFile+"_"+folderName+"_"+(suffix++)).append(".pdf").toString();
f = new File(nomeFolder);
}
return f;
}

Excel Writing results in Read-Error

I have some code that writes into an Excel file:
File file = new File("Path here");
File to = new File("Path here");
Workbook workbook = Workbook.getWorkbook(file);
WritableWorkbook target = Workbook.createWorkbook(to);
target.createSheet("s", 0);
Sheet source = workbook.getSheet(1);
WritableSheet targetSheet = target.getSheet(0);
copyRow(source, 1, targetSheet, 1);
workbook.close();
target.close();
Note that Path here is replaced with the actual path in the real code.
Where the copyRow() method looks like this:
private void copyRow(Sheet sourceSheet, int sourceRow, WritableSheet targetSheet, int targetRow) throws WriteException {
for(int i = 0, numOfColumn = sourceSheet.getColumns(); i < numOfColumn; i++) {
Cell source = sourceSheet.getCell(i, sourceRow);
WritableCell cell = new Label(i, targetRow, source.getContents());
targetSheet.addCell(cell);
}
}
It runs, but when I try to open the to file:
An error message, saying that the file cannot be opened, shows when I use my Windows computer to open the same file.
Why does that happen? How do I fix it?

Excel To image transformation

I want to convert my excel file as well as its entites(charts, tables, images) to jpeg/png images. Currently using aspose for that. Here is my code
public static int excelToImages(final String sourceFilePath, final String outFilePrefix) throws Exception {
int noOfImages = 0;
Workbook workbook = getWorkbook(sourceFilePath);
List<Worksheet> worksheets = getAllWorksheets(workbook);
if (worksheets != null) {
for (Worksheet worksheet : worksheets) {
if (worksheet.getCells().getCount() > 0) {
String outFilePath = FileUtils.getAbsoluteFilePath(outFilePrefix + (noOfImages++));
SheetRender sr = new SheetRender(worksheet, getImageOrPrintOptions());
sr.toImage(0, outFilePath);
}
}
}
return noOfImages;
}
private static ImageOrPrintOptions getImageOrPrintOptions() {
ImageOrPrintOptions imgOptions = new ImageOrPrintOptions();
imgOptions.setImageFormat(ImageFormat.getJpeg());
imgOptions.setOnePagePerSheet(true);
return imgOptions;
}
private static 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;
}
My problem is that size of output image is either split into multiple A4 size or single 1 sheet depends upon the value of
imgOptions.setOnePagePerSheet(true);
Can anybody tell me how I can customize the size of output image file?
You can try it with imgOptions.setOnlyArea(true);. That will set the size of the image to the minimal that's needed to put everything to the image. But I'm not sure if the generated image is split into A4 parts.

Categories

Resources