NPOI produces unreadable content - excel

I'm using NPOI to open an existing Excel file, make modifications, and write it back to disk.
However, when I open the file with NPOI and write it back, the file becomes damaged. Excel complains that the file "contains unreadable content", and asks whether I want to "recover the contents" of the file. When I select OK, it says:
Excel cannot open the file 'test.xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.
Here is my code:
var excelFilename = "c:\\temp\\simplefile.xlsx";
IWorkbook wb;
using (var fs = File.OpenRead(excelFilename))
{
wb = new XSSFWorkbook(fs);
}
var sheet = wb.GetSheetAt(0);
// For this sample, we don't make any modifications to the file.
// Just opening and writing it back is enough to produce this error.
using (var str = new FileStream(excelFilename, FileMode.Open, FileAccess.ReadWrite))
{
wb.Write(str);
}
"simplefile.xlsx" is an empty excel workbook created by Excel 2010.
What's happening here?

Related

How do I add a script to a Google Sheet to automatically take data from an XLSX file on Google Drive?

I'm trying to automatically update a Google Sheet from a separate XLSX file, since the XLSX file gets regularly updated, but I need to do some data cleaning. I tried doing a query and importrange neither of which can get data from an xlsx file.
It seems like I need to write a script on the Google Sheet to automatically take the data from the xlsx. Where do I add this, and how would I go about getting started? I have access to both files, so permissions shouldn't be an issue.
Suggestion: Temporarily Convert the Excel File to Google Sheets File to Extract Data
Unfortunately, there is no direct way to extract data from Excel files to Google Sheets using Google Apps Script. As a workaround, you need to first convert your excel file to Google Sheets and then extract the data from the converted file to your output Google Sheets file. You may use the following script as a basis for yours:
function importData() {
var xlsxName = "Test 1.xlsx"; //Change source file name accordingly
var convertID = convert(xlsxName).toString();
var xLSX = SpreadsheetApp.openById(convertID).getSheetByName("Input");
var ss = SpreadsheetApp.openById("<output Sheet ID>").getSheetByName("Output"); //Change output sheet ID
var lastColumn = xLSX.getLastColumn();
var lastRow = xLSX.getLastRow();
ss.getRange(1, 1, lastRow, lastColumn).setValues(xLSX.getDataRange().getValues()); //Sets values from converted xlsx data to output sheet
DriveApp.getFileById(convertID).setTrashed(true); //deletes temporary file
}
function convert(excelFileName) {
var files = DriveApp.getFilesByName(excelFileName);
var excelFile = (files.hasNext()) ? files.next() : null;
var blob = excelFile.getBlob();
var config = {
title: "[Converted File] " + excelFile.getName(), //sets the title of the converted file
parents: [{ id: excelFile.getParents().next().getId() }],
mimeType: MimeType.GOOGLE_SHEETS
};
var spreadsheet = Drive.Files.insert(config, blob);
return (spreadsheet.id); //Returns the ID of the converted file
}
This script involves:
Converting the Excel file to a temporary Google Sheets file.
Importing the data from the temporary Google Sheets file to the desired/output Google Sheets file.
Deleting the temporary Google Sheets file.
NOTE:
Expect a longer runtime when applying this script to a bigger excel file.
You may modify the script to be suitable for your current issue.
The script should be added to your desired output Google Sheets.
Do not forget to add the Drive API service to your script.
Sample Test Case:
Input:
Expected Output:

SheetJS / excel4node modify xlsx file without changing anything else

I have a JSON data like:
data = [
name: "test",
age:50,
country: "America"
]
And I read excel file which looks like that
https://imgur.com/a/InyUXxv
(File is more complex, I have more static images and a lot of more text --> around 1000 cells filled)
So The problem is that I need to fill the JSON data to the excel file.
The Excel file will allways be the same and the data will allways go to same cell.
I can read this Excel template file and update it and write it back in new file but if I do that, I lost images. New file is without images
With excel4node I can write separate images to excel file but I don't know how can i read that file and than write the same back..
Code example for xlsx npm package, where I lost images when writing same file to Excel..
Can someone help me with anything? I am stuck here for a few days and I can't find a solution..
Node.js code:
var xlsx = require("xlsx");
exports.generateExcel = async () => {
var excelFile = await
xlsx.readFile("./utilities/template.xlsx");
const { SheetNames: sheetNames } = excelFile;
var data = xlsx.utils.sheet_to_json(excelFile.Sheets[sheetNames[0]]);
console.log(data);
var ws = xlsx.utils.json_to_sheet(data);
var wb = xlsx.utils.book_new();
xlsx.utils.book_append_sheet(wb, excelFile, "Tests");
xlsx.writeFile(excelFile, "./utilities/novooo.xlsx");
};
So When I write file it is written without images. In the template.xlsx there are images (I read this file in the beginning of the code and store it as variable)

Excel and Libre Office conflict over Open XML output

Open XML is generating .xlsx files that can be read by Open Office, but not by Excel itself.
With this as my starting point( Export DataTable to Excel with Open Xml SDK in c#) I have added code to create a .xlsx file. Attempting to open with Excel, I'm asked if I want to repair the file. Saying yes gets "The workbook cannot be opened or repaired by Microsoft Excel because it's corrupt." After many hours of trying to jiggle the data from my table to make this work, I finally threw up my hands in despair and made a spreadsheet with a single number in the first cell.
Still corrupt.
Renaming it to .zip and exploring shows intact .xml files. On a whim, I took a legit .xlsx file created by Excel, unzipped it, rezipped without changing contents and renamed back to .xlsx. Excel declared it corrupt. So this is clearly not a content issue, but file a format issue. Giving up on Friday, I sent some of the sample files home and opened them there with Libre Office. There were no issues at all. File content was correct and Calc had no problem. I'm using Excel for Office 365, 32 bit.
// ignore the bits (var list) that get data from the database. I've reduced this to just the output of a single header line
List< ReportFilingHistoryModel> list = DB.Reports.Report.GetReportClientsFullHistoryFiltered<ReportFilingHistoryModel>(search, client, report, signature);
MemoryStream memStream = new MemoryStream();
using (SpreadsheetDocument workbook = SpreadsheetDocument.Create(memStream, SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new Workbook();
workbook.WorkbookPart.Workbook.Sheets = new Sheets();
var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
sheetPart.Worksheet = new Worksheet(sheetData);
Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<Sheet>().Count() > 0)
{
sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = "History" };
sheets.Append(sheet);
Row headerRow = new Row();
foreach( var s in "Foo|Bar".Split('|'))
{
var cell = new Cell();
cell.DataType = CellValues.Number;
cell.CellValue = new CellValue("5");
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
}
memStream.Seek(0, SeekOrigin.Begin);
Guid result = DB.Reports.Report.AddClientHistoryList( "test.xlsx", memStream.GetBuffer(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
return Ok(result);
This should just work. I've noticed other stack overflow discussions that direct back to the first link I mentioned above. I seem to be doing it right (and Calc concurs). There have been discussions of shared strings and whatnot, but by using plain numbers I shouldn't be having issues. What am I missing here?
In working on this, I went with the notion that some extraneous junk on the end of a .zip file is harmless. 7-Zip, Windows Explorer and Libre Office all seem to agree (as does some other zip program I used at home whose name escapes me). Excel, however, does not. Using the pointer at memStream.GetBuffer() was fine, but using its length was not. (The preceding Seek() was unnecessary.) Limiting the write of the data to a length equal to the current output position keeps Excel from going off the rails.

Modifying an Excel File in Google Drive with Apache POI

I need to modify some cells of an Excel file stored in Google Drive. I'm using Apache POI to manipulate the Excel file and I can read and modify the file, but when I commit it to Google Drive it seems to work, it returns a success code but the file is not changed in Drive. The function I'm using to save the file is:
ParcelFileDescriptor file=result.getDriveContents().getParcelFileDescriptor();
InputStream in=new FileInputStream(file.getFileDescriptor());
HSSFWorkbook wb = new HSSFWorkbook(in);
for(Componente c:listaComponentes){
HSSFSheet sheet=wb.getSheetAt(c.getHoja());
HSSFRow fila=sheet.getRow(c.getFila());
fila.getCell(celdaSerie).setCellValue(c.getSerie());
}
FileOutputStream fileOut = new FileOutputStream(file.getFileDescriptor());
wb.write(fileOut);
result.getDriveContents().commit(mGoogleApiClient, null);

chart formatting lost when save as xlsx in NPOI

I have a template xlsx, called "book3.xlsx" that contains a pre-formatted chart. All I want to do is to read my template xlsx and modify some cells and write out the a xlsx ("test.xlsx")
A strange thing happens here, if i open the result xlsx the format of the chart has changed... It has different coloring, axis is missing etc. When I used xls file format it was fine, but we should use xlsx. Anyone noticed this issue?
var file = new FileStream(#"book3.xlsx", FileMode.Open, FileAccess.Read);
var workbook = new XSSFWorkbook(file);
using (var fs = new FileStream(#"test.xlsx", FileMode.Create))
{
workbook.Write(fs);
}

Resources