Apache POI - Excel - File->Passwords->"Read-only recommended" (How to disable) - java

I have several xlsx files that have the "read-only recommended" flag set.
Is there a POI 5.x method available to disable this checkbox?
I looked through POI XML Properties with no luck.

In Office Open XML-Excel files the setting "read only recommended" is stored in /xl/workbook.xml as an attribute in a fileSharing XML-element.
...
<fileSharing readOnlyRecommended="1"/>
...
This can be set or unset using apache poi only using the low level org.openxmlformats.schemas.spreadsheetml.x2006.main.*-classes.
Complete example:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
import java.io.*;
class ExcelRemoveReadOnlyRecommended {
static void removeReadOnlyRecommended(XSSFWorkbook workbook) {
CTWorkbook ctWorkbook = workbook.getCTWorkbook();
CTFileSharing ctfilesharing = ctWorkbook.getFileSharing();
if (ctfilesharing != null) {
ctfilesharing.setReadOnlyRecommended(false);
}
}
public static void main(String[] args) throws Exception {
String sourceFilePath = "./sourceFile.xlsx";
String resultFilePath = "./resultFile.xlsx";
Workbook workbook = WorkbookFactory.create(new FileInputStream(sourceFilePath));
if (workbook instanceof XSSFWorkbook) {
removeReadOnlyRecommended((XSSFWorkbook)workbook);
}
OutputStream out = new FileOutputStream(resultFilePath);
workbook.write(out);
out.close();
workbook.close();
}
}
If the sourceFile.xlsx has set that option, but without passwords, then after running that code the resultFile.xlsx has not set that option anymore.
If passwords are set too, then decryption is needed at first and the password in fileSharing needs to be unset too. Of course then at least the decryption-password needs to be known.

Related

Editing Excel spreadsheet in Java/Android using Apache POI writes data but Excel demands repairs

I am attempting to build an Android app as a convenience wrapper for editing an Excel spreadsheet. I am using the Apache POI to interface with Excel in Java, which should be able to edit an existing workbook. The spreadsheet has no fancy formatting and the editing just changes or adds numbers. I can successfully read and write data to file. However, when I open the file in Microsoft Excel (either on mobile or on PC after transferring the file), I receive the following error message:
We found a problem with some content in 'filename.xlsx'. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes.
If I click yes, it opens the file in Read-only mode. All the data is there, nothing is missing. However, to edit the file in Excel, I must save it to a different filename, which is rather inconvenient. While I could in-principle work around it (I shouldn't need to open the file in Excel often), it seems symptomatic of more serious problems.
I have a hunch it is tangentially related to this question, where Excel was suspicious of a file which had been edited by an "untrusted" program. However, unlike that question where the file was opened in Protected Mode, here Excel is implying that the file is somehow damaged. Perhaps the issue is in the metadata?
Below is a minimum working example. When the user clicks on a button the selectFile method is called. This uses the Storage Access Framework to obtain the URI of the .xlsx file I want to edit, which is an Excel spreadsheet I created in Excel to be blank except for a number in cell A1 in Sheet1. The file is stored locally on my device (although I get the same problem when it is on OneDrive, which is where I actually want the file). This URI is then passed to the doEverything method, which does the actual work of editing the Excel file. (It also updates a textView with ID textView_data, which displays the value found in cell A1. This shows that it is reading the data properly.)
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MainActivity extends AppCompatActivity {
private TextView mText;
/**
* Opens the given workbook, increments the cell by 1, then writes and closes it.
*
* #param uri URI of XLSX file
*/
private void doEverything(Uri uri) {
if (uri == null) {
return;
}
XSSFWorkbook wb = null;
// Open the workbook
try (InputStream inp = getContentResolver().openInputStream(uri)) {
wb = (XSSFWorkbook) WorkbookFactory.create(inp);
// Increment cell A1 by 1.
XSSFCell cell = wb.getSheetAt(0).getRow(0).getCell(0);
cell.setCellValue(cell.getNumericCellValue()+1);
// Write the value of the cell to the saved textView.
mText.setText(Double.toString(cell.getNumericCellValue()));
} catch (IOException e) {
e.printStackTrace();
}
if (wb != null) {
try (OutputStream fileOut = getContentResolver().openOutputStream(uri)) {
// Write to file.
wb.write(fileOut);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Record the various Views we'll need later
mText = findViewById(R.id.textView_data);
}
/**
* Asks the user to select a .xlsx file. Called when the user presses a button.
*/
public void selectFile(View view) {
// Open an .xlsx file
openDoc.launch(new String[]{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
}
// GetContent creates an ActivityResultLauncher<String> to allow you to pass
// in the mime type you'd like to allow the user to select
ActivityResultLauncher<String[]> openDoc = registerForActivityResult(new ActivityResultContracts.OpenDocument(),
new ActivityResultCallback<Uri>() {
#Override
public void onActivityResult(Uri uri) {
doEverything(uri);
}
});
}
I am using Apache POI version 5.2.3. I am using the Microsoft Excel mobile app (Version 1.0.1 (16.0.15629.20092), 2018) and Excel 365 on desktop (Version 2209), both of which give the same issue. My phone uses Android 12 with SDK 31.
How can I edit the file without Excel thinking the file is broken?

How do you add attachments from a generic filetype using Apose.Slides using java?

How do you add attachments from a generic filetype using Apose.Slides using java?
The manual PowerPoint operation I’m trying to do programmatically is:
Insert -> Object -> From file
Is this possible with Aspose.Slides insert an Excel file as a link using java?
The below code is working fine for attaching the Excel file using aspose slides
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import com.aspose.slides.IOleEmbeddedDataInfo;
import com.aspose.slides.IOleObjectFrame;
import com.aspose.slides.OleEmbeddedDataInfo;
import com.aspose.slides.Presentation;
import com.aspose.slides.SaveFormat;
public class SetFileTypeForAnEmbeddingObject2 {
public static void main(String[] args) throws IOException {
Presentation pres = new Presentation();
try {
// Add known Ole objects
byte[] fileBytes = Files.readAllBytes(Paths.get("C:\\work\\Demo uploadt.xlsm"));
// Create Ole embedded file info
IOleEmbeddedDataInfo dataInfo = new OleEmbeddedDataInfo(fileBytes, "xls");
// Create OLE object
IOleObjectFrame oleFrame = pres.getSlides().get_Item(0).getShapes().addOleObjectFrame(150, 420, 250, 50,
dataInfo);
oleFrame.setObjectIcon(true);
pres.save("C:\\work\\" + "SetFileTypeForAnEmbeddingObject7.pptx", SaveFormat.Pptx);
} finally {
if (pres != null)
pres.dispose();
}
}
}

Apache POI PPT SLide Page setup option

I am wondering if by any mean, i can set the 'Slide sized for ' as On-ScreenShow (16:9). i mean is there any method in master object in apache poi hslf? I couldn't find it. I have added the image for the reference.
You can only have one page size per file.
To set the page dimension call SlideShow.setPageSize().
To find out which page dimensions 4:3, 16:9 or any other formats are, just create a PPT manually via Powerpoint and check its dimension - or use a Cross-multiplication:
import java.io.File;
import java.io.IOException;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
public class SlideSizes {
public static void main(String[] args) throws IOException {
String files[] = { "dim_4_3.ppt", "dim_16_9.ppt" };
for (String f : files) {
SlideShow<?,?> ppt = SlideShowFactory.create(new File(f));
System.out.println(ppt.getPageSize());
}
}
}

How to fix NotOfficeXmlFileException in java Apache POI?

I'm trying to create a new excel file with just "hello" in it.
Here's my code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
*
* #author kamal
*/
public class JavaApplication4 {
private static String dir = "";
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
try {
// TODO code application logic here
JFileChooser jc = new JFileChooser();
jc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int output = jc.showOpenDialog(null);
if(output == JFileChooser.APPROVE_OPTION){
File f = jc.getSelectedFile();
String directory = f.getAbsolutePath();
setDir(directory);
}
FileOutputStream out = new FileOutputStream(new File(getDir()+"\\Book2.xlsx"));
FileInputStream in = new FileInputStream(new File(getDir()+"\\Book2.xlsx"));
org.apache.poi.ss.usermodel.Workbook workbook = new XSSFWorkbook(in);
org.apache.poi.ss.usermodel.Sheet sheet = workbook.getSheetAt(0);
sheet.createRow(0).createCell(0).setCellValue("hello");
workbook.write(out);
workbook.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
Logger.getLogger(JavaApplication4.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* #return the dir
*/
public static String getDir() {
return dir;
}
/**
* #param dir the dir to set
*/
public static void setDir(String directory) {
dir = directory;
}
}
..And when I run it I get the following error:
Exception in thread "main" org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException: No valid entries or contents found, this is not a valid OOXML (Office Open XML) file
at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:286)
at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:758)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:327)
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:37)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:291)
at javaapplication4.JavaApplication4.main(JavaApplication4.java:46)
C:\Users\kamal\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 7 seconds)
I looked up this code in youtube and it's same but i'm not sure why am i getting the error? Can you help me with this?
I think the most likely explanations are that either the file is corrupt, or it is an older format spreadsheet file that XSSFWorkbook does not understand.
It is unlikely anyone can give you a definite diagnosis without looking at the file itself.
Okay. Today I encountered the same problem . The server was linux and the excel file is copied from windows to linux through winscp. Winscp has options like transferring the file in binary mode , text mode etc. When we copy the excel file through text mode , I got the same error you mentioned. The error got resolved when I copy the excel file using binary mode. To summarize , this issue came because we copied excel file from windows to linux. Just make sure you are copying in binary mode if using winscp. Make sure the file is copied correctly.
I was facing the same problem. I did create the Excel file by doing right click inside the folder and then ->New->Microsoft Excel Worksheet.
As a trial I removed this file and then created the new Excel through Start Menu->Microsoft Office->Excel
It worked for me, Hopefully same will work for you too.

Error With creating an excel file from java POI

Hi I would like to create an excel file from a java code, I put this code on eclipse but nothing happen
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.FileOutputStream;
public class TestPOI1 {
public static void main(String[] args) {
//create the new workbook
Workbook workbook = new HSSFWorkbook();
try {
//create the output stream to save the document on the hard drive
FileOutputStream output = new FileOutputStream("Test1.xls");
//write the file onto the hard drive
workbook.write(output);
//finish it up by closing the document
output.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
in the console, this message is written
Usage: BiffDrawingToXml [options] inputWorkbook Options:
-exclude-workbook exclude workbook-level records
-sheet-indexes output sheets with specified indexes
-sheet-namek output sheets with specified name
and I can't found my excel file in the hard drive or in the file project. thanks for help.
Actually this error you will get while the Jar is still building. Just wait for few seconds.
Right Click and then Run : It will work..!

Categories