Checking if file actually is an Excel file using EPPlus - c#

I'm using EPPlus in C# to read an Excel (.xlsx) file. The initialization is done like this:
var package = new ExcelPackage(new FileInfo(filename));
This works fine but is there any way to check if the specified filename or package is actually a valid .xlsx file? Otherwise there will be exceptions when operating on a non-Excel object, e.g. if the user accidentially opens a .zip file or else.

You can check the extension of your file:
string file = #"C:\Users\Robert\Documents\Test.txt";
string extenstion = Path.GetExtension(file);
Update
I havent found some kind of return values for the situation that some file cannot be open in the EPPlus documentation, but you can use this to catch the excetptions:
FileInfo fileInfo = new FileInfo(pathToYourFile);
ExcelPackage package = null;
try
{
package = new ExcelPackage(fileInfo);
}
catch(Exception exception)
{
...
}
If you are not in catch - thats mean it was opened correctly.

Related

MS Excel Interop - Prevent Sign In Modal When Opening a Restricted Access Workbook

I am using MS Excel Interop to parse information from a collection of Excel files. If one of these Excel files has restricted access, a Windows sign-in modal opens and pauses my program. I would like to skip over these files so that this modal does not appear.
My current code, with various settings to block any Excel warnings:
var application = new Microsoft.Office.Interop.Excel.Application();
application.DisplayAlerts = false;
application.AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityForceDisable;
var workbook = application.Workbooks.Open(filePath, UpdateLinks: 0, ReadOnly: true, IgnoreReadOnlyRecommended: true, Password: "fakePassword");
I encountered a similar issue with password protected Excel documents, but was able to prevent the enter password modal by setting a fake password in the .Open code above. This causes an exception to be thrown when a file is password protected, which I then catch and the program continues on to the next Excel file.
I was hoping the WriteResPassword option for the Open method would work similarly, but even if I specify this, the Windows sign in still appears.
Any help greatly appreciated!
I'm not particularly happy with this solution, but I have found a workaround for avoiding MS sign-in modals (and many other modals) prior to opening an Excel document.
Before opening the Excel document with MS Excel Interop, I conduct a "zip test" where I zip up the file into a temporary directory, attempt to extract it, and then immediately delete that directory.
private void ZipTest(string xlsxFilePath, string tempDirectoryPath)
{
try
{
Directory.CreateDirectory(tempDirectoryPath);
string zipPath = ZipFile(xlsxFilePath, tempDirectoryPath);
using (ZipArchive zip = System.IO.Compression.ZipFile.Open(zipPath, ZipArchiveMode.Update))
{
zip.ExtractToDirectory(tempDirectoryPath);
}
Directory.Delete(tempDirectoryPath, true);
}
catch (Exception ex)
{
if (Directory.Exists(tempDirectoryPath))
{
Directory.Delete(tempDirectoryPath, true);
}
throw ex; // Do whatever you want
}
}
private string ZipFile(string filePath, string destinationDirectory)
{
string fileName = Path.GetFileName(filePath);
string zipFileName = Path.ChangeExtension(fileName, ".zip");
string destinationPath = $"{destinationDirectory}\\{zipFileName}";
File.Copy(filePath, destinationPath, false);
return destinationPath;
}
Zipping and extracting the file will fail if the workbook has restricted access, is password protected, or otherwise can't be written to. This prevents the MS sign-in modal because the excel doc is never opened.
Note that this only works on xlsx files. Any xls files need to be converted to xlsx first.

how can we convert word to .pdf format and excel to .pdf format from c#

How can we convert the excel file and word file to .pdf format from c#. i tried the following code but it shows the an error
this is my code:
Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application();
wordDocument = appWord.Documents.Open(#"C:\Users\ITPro2\Documents\test.docx");
wordDocument.ExportAsFixedFormat(#"D:\desktop\DocTo.pdf", Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF);
and i got the following Error
The export failed because this feature is not installed. during export to pdf from word from c#
While not directly related the documentation under
https://msdn.microsoft.com/en-us/library/office/ff198122.aspx
gives a note, that if the pdf add-in is not installed, exactly this error will occur. So check your prerequisites, i.e. Office installed and the add-in, too.
1) Excel 2013 Primary Interop Assembly Class Library and it works perfectly fine under .NET 4.5.1 Just add Microsoft.Office.Interop.Excel assembly to your references and you are ready to go.
using System;
using Microsoft.Office.Interop.Excel;
namespace officeInterop
{
class Program
{
static void Main(string[] args)
{
Application app = new Application();
Workbook wkb = app.Workbooks.Open("d:\\x.xlsx");
wkb.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, "d:\\x.pdf");
}
}
}
OR
2) refer this link to convert DOC or DOCx file into PDF
http://www.rasteredge.com/how-to/csharp-imaging/pdf-convert-word-to-pdf/
Since my other comment got deleted, here is the updated version.
For converting my files to pdf in c# i used the metamorphosis libary, this could also be a solution for you.
Below is a code example from me where i used a blobstorage to download PDF files from regular files.
var converter = new SautinSoft.PdfMetamorphosis();
var ms = new MemoryStream();
await blob.DownloadToStreamAsync(ms);
ms.Seek(0, SeekOrigin.Begin);
var pdfStream = converter.DocxToPdfConvertStream(ms);
if (pdfStream != null)
{
await _storageProvider.SaveFileAsync(containerName, fileName, pdfStream);
}
ms.Close();
var result = await _storageProvider.GetFileWithAttributesAsync(containerName, fileName);
return new ServiceResponse<CloudBlockBlob>(result);
Below i posted some links with the sample code from the library itself:
Word to PDF example
Excel to PDF example

Trying to read an Excel file with EPPlus works on the server, but not through a browser

When I published my project and ran it on the server, it worked. EPPlus found all 4 worksheets, iterated through them, and uploaded my data to SQL.
But when I run it through my browser, or my coworkers browser, it shows 0 worksheets.
Any idea why this might be happening? There's not much to the code at that point, but here's that part:
using (ExcelPackage package = new ExcelPackage(new FileInfo(strFile)))
{
if (package.Workbook.Worksheets.Count <= 0)
strError = "Your Excel file does not contain any work sheets";
else
{
foreach (ExcelWorksheet worksheet in package.Workbook.Worksheets)
{
EPPlus can load a file into memory. You're just not doing it that way. I think if you do this, you're less likely to run into trouble reading it from the file system. You can turn uploaded files into a byte array without having it as a file first, but in my example I'm opening an existing file. If you provide the code for how you're uploading the file, I can update my example.
byte[] file = File.ReadAllBytes(#"C:\file.xlsx");
using (MemoryStream ms = new MemoryStream(file))
using (ExcelPackage package = new ExcelPackage(ms))
{
if (package.Workbook.Worksheets.Count == 0)
strError = "Your Excel file does not contain any work sheets";
else
{
foreach (ExcelWorksheet worksheet in package.Workbook.Worksheets)
{

How to export linq result to excel just like Linqpad

I have an object with a lot of subqueries and I want do export to excel just like Linqpad does, here is an example:
Any help?
Tks
If you include a reference to linqpad.exe in your project, you can then use it to do the export to html
eg,
List<User> users = ....
var filename = "test.html";
var writer = LINQPad.Util.CreateXhtmlWriter();
writer.Write(users);
System.IO.File.WriteAllText(filename, writer.ToString());
// Open the file in excel
Process.Start("Excel" , filename);
Excel can actually open an HTML doc, renamed "xls" - reading-in HTML table structures as Excel cells.
You'd have to output your data as HTML, though.
As noted, LinqPad is not really export to an Excel format. but it create an HTML file, and opens it with Ms-Excel.
(but for a download file, you cant force the client how open th file, but you can naming the extension to XLS, and EXCEL open it with a warning).
for generate the HTML output, LinqPad use the hyperlinq library.
void Main()
{
var filePath = Path.GetTempPath() + "output.html"; //or output.xls but with ms-excel warning
var iEnumerbleValue = Enumerable.Range(1, 500).Select(e => new { a = 1, b = e });
File.WriteAllText(filePath, CreateHtml(iEnumerbleValue).ToString());
Process.Start("EXCEL.EXE", filePath);
}
HDoc CreateHtml<T>(IEnumerable<T> coll)
{
var fields = typeof(T).GetProperties();
return H.Doc(
H.head(H.style()),
H.body(
H.table(
H.tbody(
H.tr(fields.Select(f => H.th(f.Name))),
from item in coll
select H.tr(
fields.Select(f => H.td(f.GetValue(item)))
)
)
)
)
);
}
I wanted to add this solution for the next person who comes searching. I realize it's an old question, but it's the only one that popped up in my search.
You can run lprun on the command line.
lprun -format=html yourQuery.linq > output.xls
Excel is able to open html as long as it's xls extension and not xlsx. If you use xlsx it will complain that it's in the wrong format and fail to open. With xls extension it gives a message, but it is able to open.
Just as a note-
I needed a database connection string for entity framework. I had it in the linqpad.config and it took me a while to figure out why lprun couldn't read it. You have to add the connection string section to lprun.exe.config so lprun can use it.

C# Access text file in zip archive

How can I read content of a text file inside a zip archive?
For example I have an archive qwe.zip, and insite it there's a file asd.txt, so how can I read contents of that file?
Is it possible to do without extracting the whole archive? Because it need to be done quick, when user clicks a item in a list, to show description of the archive (it needed for plugin system for another program). So extracting a whole archive isn't the best solution... because it might be few Mb, which will take at least few seconds or even more to extract... while only that single file need to be read.
You could use a library such as SharpZipLib or DotNetZip to unzip the file and fetch the contents of individual files contained inside. This operation could be performed in-memory and you don't need to store the files into a temporary folder.
Unzip to a temp-folder take the file and delete the temp-data
public static void Decompress(string outputDirectory, string zipFile)
{
try
{
if (!File.Exists(zipFile))
throw new FileNotFoundException("Zip file not found.", zipFile);
Package zipPackage = ZipPackage.Open(zipFile, FileMode.Open, FileAccess.Read);
foreach (PackagePart part in zipPackage.GetParts())
{
string targetFile = outputDirectory + "\\" + part.Uri.ToString().TrimStart('/');
using (Stream streamSource = part.GetStream(FileMode.Open, FileAccess.Read))
{
using (Stream streamDestination = File.OpenWrite(targetFile))
{
Byte[] arrBuffer = new byte[10000];
int iRead = streamSource.Read(arrBuffer, 0, arrBuffer.Length);
while (iRead > 0)
{
streamDestination.Write(arrBuffer, 0, iRead);
iRead = streamSource.Read(arrBuffer, 0, arrBuffer.Length);
}
}
}
}
}
catch (Exception)
{
throw;
}
}
Although late in the game and the question is already answered, in hope that this still might be useful for others who find this thread, I would like to add another solution.
Just today I encountered a similar problem when I wanted to check the contents of a ZIP file with C#. Other than NewProger I cannot use a third party library and need to stay within the out-of-the-box .NET classes.
You can use the System.IO.Packaging namespace and use the ZipPackage class. If it is not already included in the assembly, you need to add a reference to WindowsBase.dll.
It seems, however, that this class does not always work with every Zip file. Calling GetParts() may return an empty list although in the QuickWatch window you can find a property called _zipArchive that contains the correct contents.
If this is the case for you, you can use Reflection to get the contents of it.
On geissingert.com you can find a blog article ("Getting a list of files from a ZipPackage") that gives a coding example for this.
SharpZipLib or DotNetZip may still need to get/read the whole .zip file to unzip a file. Actually, there is still method could make you just extract special file from the .zip file without reading the entire .zip file but just reading small segment.
I needed to have insights into Excel files, I did it like so:
using (var zip = ZipFile.Open("ExcelWorkbookWithMacros.xlsm", ZipArchiveMode.Update))
{
var entry = zip.GetEntry("xl/_rels/workbook.xml.rels");
if (entry != null)
{
var tempFile = Path.GetTempFileName();
entry.ExtractToFile(tempFile, true);
var content = File.ReadAllText(tempFile);
[...]
}
}

Categories