i need to change the author name of the generated excel by apache poi in java. Currently the author name of all generated by apache is "Apache POI", i need to change it. can anyone help me on this?
Thanks in advanced.Generated by Apache poi
HSSFWorkbook is a POIDocument which has SummaryInformation.
XSSFWorkbook is a POIXMLDocument which has POIXMLProperties - POIXMLProperties.CoreProperties.
Code to set author (aka creator) for both XSSF and HSSF:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
class CreateExcelAuthor {
public static void main(String[] args) throws Exception {
String author = "Axel Richter";
Workbook workbook = new XSSFWorkbook();
//Workbook workbook = new HSSFWorkbook();
workbook.createSheet();
if (workbook instanceof XSSFWorkbook) {
((XSSFWorkbook)workbook).getProperties().getCoreProperties().setCreator(author);
} else if (workbook instanceof HSSFWorkbook) {
((HSSFWorkbook)workbook).createInformationProperties();
((HSSFWorkbook)workbook).getSummaryInformation().setAuthor(author);
}
String fileName = (workbook instanceof XSSFWorkbook)?"Excel.xlsx":"Excel.xls";
try (FileOutputStream out = new FileOutputStream(fileName) ) {
workbook.write(out);
}
workbook.close();
}
}
Related
lock rename of sheet name POI java
how to protect sheet name to not let users change it
XSSFSheet sheet = ((XSSFSheet)s);
//to lock my sheet name
sheet.lockmysheetName();
I want to protect just sheet name.
Microsoft Excel does not provide lock the sheet name on sheet level. There is a possibility to protect a workbook. That protects the structure of the workbook. This includes the lock of the sheet names but also the lock of the sheets order and the lock inserting new sheets.
This is what XSSFWorkbook.lockStructure sets.
HSSFWorkbook has nothing comparable up to now. But using InternalWorkbook and WorkbookRecordList and knowledge about the binary record stream in a binary *.xls workbook one can achieve the same.
Complete example:
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.record.Record;
import org.apache.poi.hssf.record.ProtectRecord;
import org.apache.poi.hssf.model.InternalWorkbook;
import org.apache.poi.hssf.model.WorkbookRecordList;
public class CreateExcelLockStructure {
static void lockStructure(HSSFWorkbook hssfWorkbook) {
InternalWorkbook internalWorkbook = hssfWorkbook.getInternalWorkbook();
WorkbookRecordList workbookRecordList = internalWorkbook.getWorkbookRecordList();
int protpos = workbookRecordList.getProtpos();
Record record = workbookRecordList.get(protpos);
if (record instanceof ProtectRecord) {
ProtectRecord protectRecord = (ProtectRecord)record;
protectRecord.setProtect(true);
} else {
ProtectRecord protectRecord = new ProtectRecord(true);
protpos = workbookRecordList.size() - 1;
workbookRecordList.add(protpos, protectRecord);
workbookRecordList.setProtpos(protpos);
}
}
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook(); String filePath = "./CreateExcelLockStructure.xlsx";
//Workbook workbook = new HSSFWorkbook(); String filePath = "./CreateExcelLockStructure.xls";
Sheet sheet = workbook.createSheet("SheetName1");
sheet = workbook.createSheet("SheetName2");
if (workbook instanceof XSSFWorkbook) {
XSSFWorkbook xssfWorkbook = (XSSFWorkbook)workbook;
xssfWorkbook.lockStructure();
} else if (workbook instanceof HSSFWorkbook) {
HSSFWorkbook hssfWorkbook = (HSSFWorkbook)workbook;
lockStructure(hssfWorkbook);
}
FileOutputStream out = new FileOutputStream(filePath);
workbook.write(out);
out.close();
workbook.close();
}
}
public static void main(String[] args) {
try {
FileInputStream file = new FileInputStream(new File("D://New Microsoft Excel Worksheet.xlsx"));
XSSFWorkbook wb = new XSSFWorkbook(file);
XSSFSheet sheet = wb.createSheet("newsheet5");
CTWorksheet ctSheet = sheet.getCTWorksheet();
CTCustomProperties props = ctSheet.addNewCustomProperties();
props.addNewCustomPr().setId("APACHE POI");
props.addNewCustomPr().setName("Tender no = 48");
props.addNewCustomPr().setId("APACHE POI 2");
props.addNewCustomPr().setName("tender no = 58");
ctSheet.setCustomProperties(props);
FileOutputStream out = new FileOutputStream("D://New Microsoft Excel Worksheet.xlsx");
wb.write(out);
out.close();
wb.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Xlsx file is corrupted after writing custom properties at sheet level.
I'm getting an error message as 'excel cannot open the file because the file format or file extension is not valid . Vefiry that the file has not been corrupted and the file extension matches the format of the file' when tried open the excel file.
Sheet custom properties only are useable using VBA. They are stored in the Excel file but the values are within binary document parts customProperty1.bin, customProperty2.bin, ... This is nothing what apache poi provides access to until now.
Using XSSF one needs creating the binary document part, then getting the relation Id to that binary document part. Then set CTCustomProperties - CTCustomProperty. There the Id points to the binary document part containing the value and the name is the property name.
Following complete example shows this. It is tested and works using current apache poi 4.1.2. It needs ooxml-schemas-1.4.jar being in class path because default poi-ooxml-schemas-4.1.2.jar does not contain all needed low level CT*-classes.
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import java.nio.charset.StandardCharsets;
class CreateExcelSheetCustomProperties {
static void setSheetCustomProperty(XSSFSheet sheet, String customPropertyName, String customPropertyValue) throws Exception {
OPCPackage opcpackage = sheet.getWorkbook().getPackage();
int i = opcpackage.getUnusedPartIndex("/customProperty#.bin");
PackagePartName partname = PackagingURIHelper.createPartName("/customProperty" + i + ".bin");
PackagePart part = opcpackage.createPart(partname, "application/vnd.openxmlformats-officedocument.spreadsheetml.customProperty");
POIXMLDocumentPart customProperty = new POIXMLDocumentPart(part) {
#Override
protected void commit() throws IOException {
PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream();
try {
out.write(customPropertyValue.getBytes(StandardCharsets.UTF_16LE));
out.close();
} catch (Exception ex) {
ex.printStackTrace();
};
}
};
String rId = sheet.addRelation(null, XSSFRelation.CUSTOM_PROPERTIES, customProperty).getRelationship().getId();
CTWorksheet ctSheet = sheet.getCTWorksheet();
CTCustomProperties props = ctSheet.getCustomProperties();
if (props == null) props = ctSheet.addNewCustomProperties();
CTCustomProperty prop = props.addNewCustomPr();
prop.setId(rId);
prop.setName(customPropertyName);
}
public static void main(String[] args) throws Exception {
try (XSSFWorkbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("./Excel.xlsx") ) {
XSSFSheet sheet = workbook.createSheet();
setSheetCustomProperty(sheet, "APACHE POI", "Tender no = 48");
setSheetCustomProperty(sheet, "APACHE POI 2", "tender no = 58");
workbook.write(fileout);
}
}
}
I've been struggling with the same issue and found a way to make it work, but it's far from optimal. Here it is anyway and hopefully you or someone else can come up with a better method.
package temp.temp;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomProperties;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomProperty;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
public class Temp2 {
public static void main(String[] args) {
File inputFile = new File("C:\\myspreadsheet.xlsx");
try (BufferedInputStream fis = new BufferedInputStream(new FileInputStream(inputFile))) {
XSSFWorkbook wb = new XSSFWorkbook(fis);
for (int i = 0; i < wb.getNumberOfSheets(); i++) {
XSSFSheet sheet = wb.getSheetAt(i);
System.out.println("\nSheetName=" + sheet.getSheetName());
CTWorksheet ctSheet = sheet.getCTWorksheet();
CTCustomProperties props = ctSheet.getCustomProperties();
if (props != null) {
List<CTCustomProperty> propList = props.getCustomPrList();
propList.stream().forEach((prop) -> {
POIXMLDocumentPart rel = sheet.getRelationById(prop.getId());
if (rel != null) {
try (InputStream inp = rel.getPackagePart().getInputStream()) {
byte[] inBytes = inp.readAllBytes();
// By experimentation, byte array has two bytes per character with least
// significant in first byte which is UTF-16LE encoding. Don't know why!
String value = new String(inBytes, "UTF-16LE");
System.out.println(" " + prop.getName() + "=" + value);
} catch (IOException ioe) {
//Error
}
}
});
}
}
wb.close();
} catch (Exception e) {
System.out.println(e);
}
System.out.println("End");
}
}
Note that CTWorksheet comes from poi-ooxml-schemas-xx.jar and CustomProperties from ooxml-schemas-yy.jar, so both have to be on the classpath. If you're using modules (as I am), this gives big problems! Good Luck
I want to write numbers to Excel in scientific notation. In Apache Poi it is possible to set the number format of a cell like this:
Cell cell = ...
CellStyle style = workbook.createCellStyle();
DataFormat format = workbook.createDataFormat();
style.setDataFormat(format.getFormat("#0.00"));
cell.setCellStyle(style);
But when I use a pattern like "#0.00E0" I get an error from Excel when opening the file and the number format is lost.
Here is a full example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class Main {
public static void main(String[] args) {
try (Workbook wb = new XSSFWorkbook();
FileOutputStream fos = new FileOutputStream("out.xlsx")) {
Sheet sheet = wb.createSheet();
Cell cell = sheet.createRow(0).createCell(0);
CellStyle style = wb.createCellStyle();
DataFormat format = wb.createDataFormat();
style.setDataFormat(format.getFormat("#0.00E0"));
cell.setCellStyle(style);
cell.setCellValue(Math.random());
wb.write(fos);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thanks!
The correct format for scientific notation would be:
format.getFormat("0.00E+00")
Someone knows why XSSFSheets doesn't provide a method to get its password like the HSSFSheet does with http://javadox.com/org.apache.poi/poi/3.13/org/apache/poi/hssf/usermodel/HSSFSheet.html#getPassword()
The question is why would you need that unsafe short two bytes "password hash"?
But:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
public class ExcelHSSFXSSFProtectedSheetPassword {
public static void main(String[] args) throws Exception {
Workbook hssfworkbook = new HSSFWorkbook();
Sheet sheet = hssfworkbook.createSheet();
sheet.protectSheet("passwordExcel");
short pwdHash = ((HSSFSheet)sheet).getPassword();
System.out.println(pwdHash);
hssfworkbook.close();
Workbook xssfworkbook = new XSSFWorkbook();
sheet = xssfworkbook.createSheet();
sheet.protectSheet("passwordExcel");
byte[] pwdBytes = ((XSSFSheet)sheet).getCTWorksheet().getSheetProtection().getPassword();
pwdHash = java.nio.ByteBuffer.wrap(pwdBytes).order(java.nio.ByteOrder.BIG_ENDIAN).getShort();
System.out.println(pwdHash);
xssfworkbook.close();
}
}
I have downloaded Apache Poi Jar but when I write the following code (which a youtube instructor ran with ease), it does not give me any output excel file. What am I doing wrong here? I hover my mouse over HSSFWorkbook eclipse tells me
org.apache.poi.hssf.usermodel.HSSFWorkbook Note: This element neither has attached source nor attached Javadoc and hence no Javadoc could be found.
The code.
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class WriteExcel {
public static void main(String[] args) throws FileNotFoundException, IOException {
HSSFWorkbook workbook= new HSSFWorkbook();
HSSFSheet sheet= workbook.createSheet("FirstExcelSheet");
HSSFRow row= sheet.createRow(0);
HSSFCell cell= row.createCell(0);
cell.setCellValue("1,Cell");
workbook.write(new FileOutputStream("excel.xls"));
workbook.close();
workbook.getFirstVisibleTab();
}
}
the first thing use XSSFWorkbook instead of HSSFWorkbook take a look at this link,
and the second thing you have to out stream this file add this line
try (FileOutputStream outputStream = new FileOutputStream("slsx.xlsx")) {
workbook.write(outputStream);
so your code should be like this
public static void main(String[] args) throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet spreadsheet = workbook.createSheet("sheet1");
XSSFRow row = spreadsheet.createRow(1);
XSSFCell cell = row.createCell(1);
cell.setCellValue("test");
try (FileOutputStream out = new FileOutputStream(new File("Writesheet.xlsx"))) {
workbook.write(out);
}
System.out.println("Writesheet.xlsx written successfully");
}
you should add your path in this line like:
workbook.write(new FileOutputStream("{yourpath}/excel.xls"));
it works..