Protect a sheet results in a corrupt workbook - apache-poi

I want to copy an Excel Workbook with apache poi. The copy must be protected but the user should be able to resize the columns. I prepared a template and picked "columns format" on the first sheet in the template. When I use the following snippet
InputStream is = new FileInputStream(
new File(DIR, "template.xlsx"));
XSSFWorkbook wb = (XSSFWorkbook) WorkbookFactory.create(is);
XSSFSheet s = wb.getSheetAt(0);
s.protectSheet("");
FileOutputStream os = new FileOutputStream(new File(DIR, "test.xlsx"));
wb.write(os);
os.close();
I get a corrupt Excelsheet. I use apache poi 3.8 and Excel 2007.
Is there a workaround for protecting the sheets but allow to resize the columns?
Any help would be greatly appreciated
stephan

I know this is an old post, but I just solved this problem. You can use the following code:
//just initialize these
XSSFWorkbook xwb;
XSSFSheet xsheet;
xsheet.protectSheet("1234");
xsheet.getCTWorksheet().getSheetProtection().setFormatColumns(false);
xsheet.enableLocking();
xwb.lockStructure();
Hope this helps somebody in the future! :D

Related

How to add image file as Ole object in excel using java

I tried with Aspose cell.
But I am able to add pdf file properly.
When I add jpg file, it shows in the excel file but doesnot get opened.
I tried with following way.
sheet.getOleObjects().get(oleObjectIndex).setImageData(binary);
sheet.getOleObjects().get(oleObjectIndex).setLeftCM(oleObjectIndex);
sheet.getOleObjects().get(oleObjectIndex).setDisplayAsIcon(true);
Here image shown like a thumbnail , but I dont want that.
sheet.getOleObjects().get(oleObjectIndex).setObjectData(binary);
//sheet.getOleObjects().get(oleObjectIndex).setFileType(oleFileType);
sheet.getOleObjects().get(oleObjectIndex).setDisplayAsIcon(true);
sheet.getOleObjects().get(oleObjectIndex).setLeftCM(oleObjectIndex);
Here it shows proper icon for the file but file does not get opened when double clicked.
Help from the community is highly apraciated.
Thank you.
See the following two lines of code that you also need to add:
sheet.getOleObjects().get(oleObjectIndex).setFileFormatType(FileFormatType.UNKNOWN);
sheet.getOleObjects().get(oleObjectIndex).setObjectSourceFullName(path);
Here is complete sample code that I tested and it works fine:
e.g
Sample code:
// Get the image file.
String path = "e:\\test\\myfile.jpg";
File file = new File(path);
// Get the picture into the streams.
byte[] img = new byte[(int) file.length()];
FileInputStream fis = new FileInputStream(file);
fis.read(img);
// Instantiate a new Workbook.
Workbook wb = new Workbook();
// Get the first worksheet.
Worksheet sheet = wb.getWorksheets().get(0);
// Add an Ole object into the worksheet with the image shown in MS Excel.
int oleObjIndex = sheet.getOleObjects().add(14, 3, 200, 220, img);
OleObject oleObj = sheet.getOleObjects().get(oleObjIndex);
// Set embedded ole object data and other attributes.
oleObj.setObjectData(img);
oleObj.setDisplayAsIcon(true);
oleObj.setFileFormatType(com.aspose.cells.FileFormatType.UNKNOWN);
oleObj.setObjectSourceFullName(path);
// Save the excel file
wb.save("f:\\files\\tstoleobject1.xlsx");
Hope, this helps a bit.
PS. I am working as Support developer/ Evangelist at Aspose.
i just use the same code,but i found when i open the new Excel,it shows as a image,i have to check it twice to transfer it to an OLE.
whats worry

How to create a new sheet and write some data in the existing excel using selenium java

I tried the below code.
But it overwrite the existing sheet.
File f= new File(System.getProperty("user.dir")+"\\src\\test\\resources\\Exceldata.xls");
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet worksheet= workbook.createSheet("Sheet4");
HSSFRow row = worksheet.createRow(1);
HSSFCell cell= row.createCell(1);
cell.setCellValue("admin");
enter code here
workbook.write(f);
workbook.close();
Use FileInputStream instead of File and and object of XSSFWorkbook
I hope this function may help you,
public static void write(){
try
{
FileInputStream myxls = new FileInputStream(System.getProperty("user.dir")+"\\src\\test\\resources\\Exceldata.xls" );
HSSFWorkbook studentsSheet = new HSSFWorkbook(myxls);
workbook = new XSSFWorkbook(myxls );
workbook.createSheet(sheetname);
HSSFSheet worksheet = studentsSheet.getSheetAt(0);
a=worksheet.getLastRowNum();
System.out.println(a);
Row row = worksheet.createRow(++a);
row.createCell(1).setCellValue("");
myxls.close();
FileOutputStream output_file =new FileOutputStream(new File(System.getProperty("user.dir")+"\\src\\test\\resources\\Exceldata.xls"));
//write changes
workbook.write(output_file );
studentsSheet.write(output_file);
output_file.close();
System.out.println(" is successfully written");
}
Try calling this function from main maethod,
public static void main(String args[])
{
write();
}
Possible duplicate of Append Data in existing Excel file using apache poi in java and
How to add new sheets to existing excel workbook using apache POI?
I finally found out the solution. i had used poi jar 4.0 in which i could not succeed in writing data. I then downgraded the jar version to 3.14 and i works perfectly

I want to add new sheet to an existing csv file, but I dont know how to go about it

I want to add new sheet to an existing csv file, but I dont know how to go about it. I already opened the .csv file and i can access each element. so i want to create a new sheet on the existing .csv file and populate the cells with the data from the previous sheet.
class Program
{
static void Main(string[] args)
{
var reader = new StreamReader(File.OpenRead(#"C:\Users\Desktop\test.csv"));
List<string> listA = new List<string>();
List<string> listB = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
//line = line.Skip(1);
var values = line.Split(',');
listA.Add(values[0]);
listB.Add(values[1]);
listA.ForEach(Console.WriteLine);
listB.ForEach(Console.WriteLine);
Console.ReadLine();
}
}
}
I'm going to post this as an answer, even though it's kind of a non-answer. CSV files are simple flat-text files that are comma delimited. There are no higher-level concepts to this file type such as sheets, or cells, workbooks, or formulas.
Since they are just simple text files that are specially formatted, there is no concept of sheets. Instead you can maybe create additional CSV files and name the files accordingly.
If you want to create Excel files, and have individual sheets you can use various libraries or the COM Interops to do this.
COM Interops are for direct connections to Excel natively. Here's a MSDN How-To for Excel. This allows you to create a special object that will allow you to use Excel's API even though it's not a managed API through the .NET Framework.
Here's an example on how to add a sheet in that situation:
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
Console.WriteLine("EXCEL could not be started. Check that your office installation and project references are correct.");
return;
}
xlApp.Visible = true;
Workbook wb = xlApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet); //adds worksheet to our workbook
Worksheet ws = (Worksheet)wb.Worksheets[1]; //access that worksheet linked into the workbook
if (ws == null)
{
Console.WriteLine("Worksheet could not be created. Check that your office installation and project references are correct.");
}
Another option is to use the Open XML SDK for Office, which can be used for the new Office formats (.xlsx for example). Personally, I've never used this library, but it's similar to Apache POI for the .NET Framework.

How to check exact style from two excel file using apache poi?

I want to compare two excel file cell style. By using apache poi how can i compare styles cell by cell?
And also i need which style is not matched, like align or bold or color..etc. That means unmatched styles should be a string(style name - align, color....)
With Cell.getCellStyle() you can find out the style per cell. With that you can check the fine granular CellStyle settings.
You might do it this way:
sheet.getRow(0).getCell(0).getCellStyle().getCoreXf();
The getCoreXf() method returns:
<xml-fragment numFmtId="14" fontId="0" fillId="2" borderId="0" xfId="0" applyNumberFormat="1" applyFill="1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"/>
Sample code (to compare styles of two cells):
FileInputStream file = new FileInputStream(new File("res/Book1.xlsx"));
//Get the workbook instance for XLS file
XSSFWorkbook workbook = new XSSFWorkbook (file);
//Get first sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
CTXf style1 = sheet.getRow(0).getCell(0).getCellStyle().getCoreXf();
CTXf style2 = sheet.getRow(0).getCell(1).getCellStyle().getCoreXf();
System.out.println(style1);
System.out.println(style1.equals(style2)); //true if both are same and false if they are different
This seems to be working fine. Please try!

Creating excel sheet from template in Java, new versions of Excel

I found the following code to create a excel sheet from an existing template with formats and add data to it and save it to a new file
POIFSFileSystem fs = new POIFSFileSystem(
new FileInputStream("template.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs, true);
Will load an xls, preserving its structure (macros included). You can then modify it,
HSSFSheet sheet1 = wb.getSheet("Data"); ...
and then save it.
FileOutputStream fileOut = new FileOutputStream("new.xls");
wb.write(fileOut);
fileOut.close();
This works absolutely fine. But my issue is that I am dealing with new versions of excel now. So I need to develop a similar code to handle new version of template. Can someone suggest how can I do this? I tried changing HSSWorkbook to XSSFWorkbook. however XSSFWorkbook doesn't have a constructor that lets me pass a boolean. Also. when i tried it, it copies the data but the rows with data do not retain the formatting of the columns that the template has.
This should work fine (though it's always best to use the latest version of POI for all the bug fixes):
Workbook wb = new XSSFWorkbook( OPCPackage.open("template.xlsx") );
Sheet sheet = wb.getSheetAt(0);
// Make changes to the sheet
sheet.getRow(2).getCell(0).setCellValue("Changed value"); // For example
// All done
FileOutputStream fileOut = new FileOutputStream("new.xls");
wb.write(fileOut);
fileOut.close();
If you code against the interfaces, then you can just swap between HSSF and XSSF in your constructor, and have your code work for both formats
I used XSSF and it is working fine.
XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream("template.xlsx"));
FileOutputStream fileOut = new FileOutputStream("new.xlsx");
//Sheet mySheet = wb.getSheetAt(0);
XSSFSheet sheet1 = wb.getSheet("Summary");
XSSFRow row = sheet1.getRow(15);
XSSFCell cell = row.getCell(3);
cell.setCellValue("Bharthan");
wb.write(fileOut);
log.info("Written xls file");
fileOut.close();
Just need to add this dependency in pom.xml of maven
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8-beta4</version>
</dependency>

Resources