Is there a way to produce a workbook using NPOI that has doesn't allow user to edit the workbook unless saving a new copy?
Basically I want to produce a file that is a read-only excel, and that no users will have conflict when opening them when accessing them on a shared network drive.
P/S: I am not looking for password protection.
var wb = new XSSFWorkbook();
var sheet = wb.CreateSheet("Sheet1");
sheet.CreateRow(0).CreateCell(0).SetCellValue("Hello World");
wb.SetReadOnly(true);//Something like this?
Readonly is an attribute for file
File.SetAttributes("workbook.xlsx", FileAttributes.ReadOnly);
You don't need to that with NPOI library
to set security permission for all files in a directory
var directory = new DirectoryInfo(folderPath);
foreach (var file in di.GetFiles("*", SearchOption.AllDirectories))
{
File.SetAttributes(folderPath, FileAttributes.ReadOnly);
}
or for a specific file
File.SetAttributes(folderPath, FileAttributes.ReadOnly);
Related
I have created an Excel Add-in using VSTO in C#. I want to create a new Excel file from a template located on a SharePoint site. A file picker dialog box is used so the user can chose which file to use as a template. Everything works fine exept the new workbook is created as read only. If I copy the template file on my computer, and use the same program to pick that file as a template, the new workbook is not created as read only.
The file on the sharePoint is not being open elseware when creathing the new file. Is there a way to specify the sharePoint library is a safe source? Or to set the newly created workbook readonly property to false?
{
string pathSP= #”\\Business.sharepoint.com#SSL\teams\group\NDC\”;
if (System.IO.Directory.Exists(pathSP))
{
Excel.Application excelObj = Globals.ThisAddIn.Application;
Office.FileDialog fileDialog = excelObj.FileDialog[Office.MsoFileDialogType.msoFileDialogFilePicker];
fileDialog.InitialFileName = initialPath;
fileDialog.AllowMultiSelect = false;
fileDialog.InitialView = Office.MsoFileDialogView.msoFileDialogViewDetails;
fileDialog.Title = "Create Excel file from template";
fileDialog.Filters.Clear();
fileDialog.Filters.Add("Excel template", "*.xls; *.xlsx; *.xlsm; *.xltx; *.xltm; *.xlt", 1);
string TemplatePath;
if (fileDialog.Show() == -1)
{
templatePath = fileDialog.SelectedItems.Item(1);
fileDialog = null;
}
else
{
templatePath=""
fileDialog = null;
}
if (templatePath != "")
{
Excel.Workbook ws= excelObj.Workbooks.Add(templatePath);
}
}
else
{
MessageBox.Show("SharePoint site is not available", "Create Excel file from template", MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
}
}
for the two ways you mentioned:
set the share point library as a safe source - this can be achieved by setting the excel setting: Options -> Trust Centre -> Trust Centre Settings -> Trusted Locations -> add the sharepont location
set the file access (readonly=false) at the end of your process
Actually as a general practice when dealing with template file (not limited to excel), the system should copy the template file to a local temp location (ideally the running user's TEMP folder), use it and then delete it afterwards. this way would avoid all kinds of problems such as file-lock-by-other-user/process problems.
So I think your problem is the Workbooks.Add(). Check out what Microsoft says about it:
[Workbooks.Add()] Determines how the new workbook is created. If this argument is a string specifying the name of an existing Microsoft Excel file, the new workbook is created with the specified file as a template.
I believe the workbook you're creating is a carbon copy of whatever the sharepoint server has, including permissions. The fact it works locally is another clue that sharepoint might be fiddling with permissions.
I suggest try saving a copy of the file locally. You can even use the SaveFileDialog object to give the user a GUI to save their new copy.
SaveFileDialog userSaveFileDialog = new SaveFileDialog();
userSaveFileDialog.Filter = "Excel 2007 and later | *.xlsx, Excel Macro Enabled Worksheet | *.xlsm, I'm guessing this is a 2007 template | *.xltx, Template Macro maybe | *.xltm, I almost definitely think this is a template file | *.xlt";
userSaveFileDialog.Title = "Save an Excel File";
userSaveFileDialog.ShowDialog();
this.Application.ActiveWorkbook.SaveCopyAs(#userSaveFileDialog.FileName);
Once you're done, you can programmatically open the newly saved workbook using userSaveFileDialog.FileName as your filepath.
I am attempting to open a password protected excel file (versions xls, xlsx, xlsm). I need to open the files and remove the password from each file.
I have all the passwords available for the files that are to be processed.
I cant use Microsoft Interop Excel as excel must be installed on the server for this to work. I am already using Aspose.Cells to open non password protected files. But i want to be able to save the file overwrite it without its password.
Has anybody any suggestions? Thanks in advance
Code so far
public static void RemovePassword(string filePath, string password){
LoadOptions loadOptions = new LoadOptions();
loadOptions.Password = password;
Workbook src = new Workbook(filePath, loadOptions);
//need a way of removing the password from the file.
}
You can use the Unprotect method of Workbook:
LoadOptions loadOptions = new LoadOptions();
loadOptions.Password = password;
Workbook workbook = new Workbook(filePath, loadOptions);
workbook.Unprotect(password);
// or workbook.Settings.Password = "";
workbook.Save(filePath);
Thanks for your answer, I have noticed that your first suggestion only unprotects the workbooks structure.
workbook.Unprotect(password);
In my case i want to unencrypt an actual file that is password protected(encrypted)
The second suggestion works great thanks!
workbook.Settings.Password = "";
workbook.Save(filePath);
Thanks Again for your help
I have a folder with over 2000+ MS Excel 2010 .XLSX spreadsheets and I need to perform the following actions:
I need to open each individual file
Copy the content of cell B4 (+ each file has unique content on cell B4), and
append the content of cell B4 to the original file name
How can I fix this error so I can successfully rename my spreadsheets as mentioned above?
//file rename code
DirectoryInfo d = new DirectoryInfo(#"C:\Torename\");
FileInfo[] infos = d.GetFiles();
foreach (FileInfo f in infos)
{
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = excel.Workbooks.Open(f.FullName);
Worksheet excelSheet = wb.ActiveSheet;
//Read the first cell
string test = excelSheet.Cells[4, 2].Value.ToString();
File.Move(f.Name, new_filename);
***Thank you for your assistance that did the trick
File.Move(f.FullName, new_filename);
You have to use FullName, you need the full path.
Edit: Not part of your Question, but:
I'm not sure how Workbooks.Open works, but if you run into errors you might close the file before renaming it.
Also Adams comment.
Close the workbook before moving it. Make sure to release all the resources associated with that file.
And make sure you use the whole path in the names
I'm writing a program to process some excel documents, the program is written in C# in Visual Studio 2010, and I'm using the NPOI library.
I notice the I was not able to use CloneSheet() for the xlsm file, but I was able to do so with xlsx.
CloneSheet() is a function that I really need for the process, so I really would like to get it working instead of copy everything cell by cell.
I thought of converting the file to xlsx. I was able to do it manually, but not programmatically.
This is the code I wrote to attempt to do so:
XSSFWorkbook workbook;
//read original xlsm file into workbook
using (FileStream file = new FileStream(#"OriginalFile\" + filename, FileMode.Open, FileAccess.Read))
{ workbook = new XSSFWorkbook(file); }
//change file extension to xlsx and save in a new location
filename = Path.ChangeExtension(filename, "xlsx");
if (!Directory.Exists("NewFile"))
Directory.CreateDirectory("NewFile");
FileStream stream = new FileStream(("NewFile\\New" + filename), FileMode.Create, System.IO.FileAccess.Write);
workbook.Write(stream);
stream.Close();
//read the newly created file from the new location
using (FileStream file = new FileStream(#"NewFile\\New" + filename, FileMode.Open, FileAccess.Read))
{ workbook = new XSSFWorkbook(file); }
The above code will create the new xlsx file, but the file cannot be open and seems to be corrupted...
I've been googling for a while and couldn't seem to find a solution, can anyone help or point me to the right direction?
--EDIT---
I tried a different method using Open XML I found here, but I have the same issue, where the file is created but I can't open the file.
However, the file doesn't seem to be corrupted. My program that is reading the file have no problem reading the data, and when I try to open the file in excel it's saying "The file is a macro-free file, but contains macro-enable content."
Seems like I'm getting closer, but I need to be able to open the output file otherwise it's no use....
You may have to roll your own method: iterate rows then cells. This post Copy Row Helper got me started. You'll have to modify it to use two workbooks. This method will copy data and formulas. CellStyles will have to be recreated as they they specific to the originating workbook.
I want to get only active sheet name from excel file using c#,but now i am getting all the sheet names,how can i get only active sheet name from excel using c#?
you can use the ActiveSheet property to get the name out of it
See link here http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._application.activesheet
e.g.
WorkSheet sheet = (WorkSheet)_application.activesheet;
string name = sheet.Name;
You may want to use NugetPackage Library NPOI (https://archive.codeplex.com/?p=npoi).
You can retrieve lots of useful information about Excel files (XLSX or XLS). Including the active worksheet when the workbook was saved (ActiveSheetIndex property).
It has the advantage of not relying on Microsoft Interpot API (not requiring Excel to be installed).
You may try this:
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
...
//Stream
FileStream arquivoXLSX = new FileStream(XLSXWorkbokPath, FileMode.Open, FileAccess.Read);
//Workbook Data from XML
XSSFWorkbook workbook = new XSSFWorkbook(XLSXWorkbokPath);
//Active Worksheet Index
var ActWsIndex = workbook.ActiveSheetIndex;
//Active Worksheet Name
var ActWsName = workbook.GetSheetName(ActWsIndex);
I hope it helps.