how to get the objects embedded in excel usng C# - c#

I have an application where I need to get the objects that are embedded in excel should be stored in some location through code.
connection.Close();
//connection.ResetState();
string embeddingPartString;
//ArrayList chkdLstEmbeddedFiles = new ArrayList(); ;
List<String> chkdLstEmbeddedFiles = new List<string>();
//string fileName = txtSourceFile.Text;
if (filepath == string.Empty || !System.IO.File.Exists(filepath))
{
return;
}
// Open the package file
pkg = Package.Open(filepath, FileMode.Open, FileAccess.ReadWrite);
System.IO.FileInfo fi = new System.IO.FileInfo(filepath);
string extension = fi.Extension.ToLower();
if ((extension == ".docx") || (extension == ".dotx") || (extension == ".docm") || (extension == ".dotm"))
{
embeddingPartString = "/word/embeddings/";
}
else if ((extension == ".xlsx") || (extension == ".xlsm") || (extension == ".xltx") || (extension == ".xltm"))
{
embeddingPartString = "/xl/embeddings/";
}
else
{
embeddingPartString = "/ppt/embeddings/";
}
// Get the embedded files names.
foreach (PackagePart pkgPart in pkg.GetParts())
{
if (pkgPart.Uri.ToString().StartsWith(embeddingPartString))
{
string fileName1 = pkgPart.Uri.ToString().Remove(0, embeddingPartString.Length);
chkdLstEmbeddedFiles.Add(fileName1);
}
}
//pkg.Close();
if (chkdLstEmbeddedFiles.Count == 0)
//MessageBox.Show("The file does not contain any embedded files.");
// Open the package and loop through parts
// Check if the part uri to find if it contains the selected items in checked list box
pkg = Package.Open(filepath);
foreach (PackagePart pkgPart in pkg.GetParts())
{
for (int i = 0; i < chkdLstEmbeddedFiles.Count; i++)
{
object chkditem = chkdLstEmbeddedFiles[i];
if (pkgPart.Uri.ToString().Contains(embeddingPartString + chkdLstEmbeddedFiles[i].ToString()))
{
// Get the file name
string fileName1 = pkgPart.Uri.ToString().Remove(0, embeddingPartString.Length);
// Get the stream from the part
System.IO.Stream partStream = pkgPart.GetStream();
//string filePath = txtDestinationFolder.Text + "\\" + fileName1;
// Write the steam to the file.
Environment.GetEnvironmentVariable("userprofile");
System.IO.FileStream writeStream = new System.IO.FileStream(#"C:\Users\jyshet\Documents\MicrosoftDoc_File.docx", FileMode.Create, FileAccess.Write);
ReadWriteStream(pkgPart.GetStream(), writeStream);
// If the file is a structured storage file stored as a oleObjectXX.bin file
// Use Ole10Native class to extract the contents inside it.
if (fileName1.Contains("oleObject"))
{
// The Ole10Native class is defined in Ole10Native.cs file
// Ole10Native.ExtractFile(filePath, txtDestinationFolder.Text);
}
}
}
}
pkg.Close();
I am able to download only doc file and rest are not seen like txt and mht files. Please suggest what to do in this case. My problem is any objects embedded in excel should be downloaded thru code and saved in destination.

Related

Saving Multiple Files At Once

I've been trying to figure out how to use the SaveFileDialog function in c# to save more than one file at a time.
The basic idea is, after the user has set parameters for a .cfg file, the user types out a set of serial numbers for which to save the configuration as. Then a SaveFileDialog is called allowing the user to save the one .cfg file under the names of the serial numbers the user listed.
Is this possible to do? Do you need to put the function into a loop, or is there another way to achieve this goal?
the .cfg file is set up like:
timezone=1
auto_DST=1
location=0
alarm_time=21
alarm_seconds_P=0
etc.
Here is what I have so far for saving that file:
List<Parameter> _paramList = new List<Parameter>();
List<Information> _infoList = new List<Information>();
saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
saveFileDialog1.DefaultExt = ".CFG";
saveFileDialog1.FileName = ( "config_" + txtParamValue.Text);
saveFileDialog1.Filter = "Configuration files (*.CFG)|*.CFG|All files (*.*)|*.*";
if ( saveFileDialog1.ShowDialog( ) == DialogResult.OK )
{
using ( StreamWriter objWriter = new StreamWriter( saveFileDialog1.FileName ) )
{
foreach (Parameter p in _paramList)
{
String name = p.ParameterName.Trim();
String val = p.ParameterValue.Trim();
foreach (Information i in _infoList)
{
if (p.ParameterName.Trim() == i.SimpleName)
{
name = i.InfoName;
if (i.InputChoice == "1")
{
if (p.ParameterValue == "On")
val = "1";
else
val = "0";
}
break;
}
else if (p.ParameterName.Trim() == i.InfoName)
{
if (p.ParameterValue == "On")
val = "1";
else
val = "0";
break;
}
}
if (name == "location" && val != location_update)
{
name = "location_update";
}
objWriter.WriteLine(name + "=" + val);
}
objWriter.Close();
}
}

How to display image angular from .net core API and database

I would like to display a picture whose path it stores in the database
this is how it transfers the image file to the database.
public string UploadImage(IFormFile file)
{
if (file == null) throw new Exception("Pusty plik");
if (file.Length == 0)
{
throw new Exception("Pusty plik");
}
if (!ACCEPTED_FILE_TYPES.Any(s => s == Path.GetExtension(file.FileName).ToLower())) throw new Exception("Zły typ pliku");
if (string.IsNullOrWhiteSpace(host.WebRootPath))
{
host.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
}
var uploadFilesPath = Path.Combine(host.WebRootPath, "images");
if (!Directory.Exists(uploadFilesPath))
Directory.CreateDirectory(uploadFilesPath);
var fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
var filePath = Path.Combine(uploadFilesPath, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
file.CopyToAsync(stream);
}
var path = Path.Combine(Directory.GetCurrentDirectory(), #"/wwwroot/images/", fileName);
return path;
}
here stores files:
https://zapodaj.net/a8829a7a3a90b.png.html
In your sample code I do not see path returning from database.
Also from security point of view it would be bad practice to return /wwwroot/images/ in response. You can create a folder on shared location and return shared location path.
Seems you question and same code isn't aligning.

Create multi-file zip from stream and download on the fly

I'm using DotNetZip library to make multi-file zip archive and download it on the fly (no need to wait for download to start). However I can't make it to download instantly. From browser dev console, in network tab I noticed that first zip file is "transferred" and after being fully transferred it starts downloading.
Here is code fragment:
using (var vZipArchive = new ZipFile())
{
if (vFilesTable.Rows.Count > 0)
{
string vPathFormat = null;
string vKeyName = null;
string vPrimKey = null;
string vFileName = null;
vZipArchive.CompressionLevel = CompressionLevel.BestSpeed;
vZipArchive.CompressionMethod = CompressionMethod.Deflate;
vZipArchive.Comment = "Document Archive";
foreach (DataRow vFile in vFilesTable.Rows)
{
if (vKeyFieldName != null && !string.IsNullOrEmpty(vKeyFieldName))
{
vPathFormat = "{0}/";
}
else
{
vPathFormat = "/";
}
if (vFile.Table.Columns.Contains("FileName") && vFile.Table.Columns.Contains("PrimKey"))
{
vPrimKey = vFile["PrimKey"].ToString();
vFileName = vFile["FileName"].ToString();
if (vKeyFieldName != null)
{
vKeyName = vFile[vKeyFieldName].ToString();
}
string vPath = null;
if (vKeyFieldName != null)
{
vPath = string.Format(vKeyFieldName + " " + vPathFormat + "{1}", vKeyName, vFileName);
}
else
{
vPath = string.Format(vPathFormat + vFileName);
}
using (var vFileStream = vUserContext.GetFileStream(vRecordSource.ViewName, new Guid(vPrimKey)))
{
vFileStream.Position = 0;
vZipArchive.AddEntry(vPath, vFileStream);
}
}
else
{
throw new Exception("Select 'FileName' and 'PrimKey' fields in underlying DataSource");
}
} //end loop
pContext.Response.Clear();
pContext.Response.BufferOutput = false;
pContext.Response.ContentType = "application/zip";
pContext.Response.AddHeader("Content-Disposition", string.Format("attachment; filename=\"{0}.zip\"", vZipName));
vZipArchive.Save(pContext.Response.OutputStream);
}
else
{
return;
}
}
I also tried using ZipOutputStream and SharpCompress.dll library.
So, what I am missing to make it work? Or its impossible?

Can not delete the existing file in C#.net

I am trying to upload a file in asp.net. File may be image or pdf. If the file already exist then I have to remove existing file and upload the new file. But if I try to delete existing file, it shows an error that "The process cannot access the file because it is being used by another process"
This is the code for my file upload.
if (FileUploadFollowUpUN.HasFile)
{
if (Request.QueryString.Count > 0 && Request.QueryString["PCD"] != null)
{
filename = System.IO.Path.GetFileName(FileUploadFollowUpUN.FileName.Replace(FileUploadFollowUpUN.FileName, Request.QueryString["PCD"] + " " + "D" + Path.GetExtension(FileUploadFollowUpUN.FileName)));
SaveFilePath = Server.MapPath("~\\ECG\\") + filename;
DirectoryInfo oDirectoryInfo = new DirectoryInfo(Server.MapPath("~\\ECG\\"));
if (!oDirectoryInfo.Exists)
Directory.CreateDirectory(Server.MapPath("~\\ECG\\"));
if (File.Exists(SaveFilePath))
{
File.SetAttributes(SaveFilePath, FileAttributes.Normal);
File.Delete(SaveFilePath);
}
FileUploadFollowUpUN.SaveAs(Server.MapPath(this.UploadFolderPath) + filename);
Session["FileNameFollowUpUN"] = filename;
if (System.IO.Path.GetExtension(FileUploadFollowUpUN.FileName) == ".pdf")
{
imgPhoto.ImageUrl = "~/Images/pdf.jpg";
ZoomImage.ImageUrl = "~/Images/pdf.jpg";
imgPhoto.Enabled = true;
}
else
{
imgPhoto.ImageUrl = "~/ECG/" + filename;
imgPhoto.Enabled = true;
ZoomImage.ImageUrl = "~/ECG/" + filename;
}
}
}
How can I get rid out of this error?
There is a similar question here on how to find what process is using a file
You should try to dispose any file methods before trying to delete.
You could stick it in a while loop if you have something which will block until the file is accessible
public static bool IsFileReady(String sFilename)
{
// If the file can be opened for exclusive access it means that the file
// is no longer locked by another process.
try
{
using (FileStream inputStream = File.Open(sFilename, FileMode.Open, FileAccess.Read, FileShare.None))
{
if (inputStream.Length > 0)
{
return true;
}
else
{
return false;
}
}
}
catch (Exception)
{
return false;
}
}

Check for (.csv or .dat) file extension among multiple files and if not send alert to the user

I am new to SSIS,
Every 30 mins I will receive a single file or multiple files in the Source Directory
I need to loop through these files and check if it has a .csv or .dat extension:
If it is not: send alert to the user.
If it is: execute the package
EDIT : I have tried;
Main()
{
try
{
string[] filenames;
filenames = Directory.GetFiles(#"C:Input_Data\");
string FileExtension = Path.GetExtension("filenames");
if (FileExtension == ".DAT" && FileExtension == ".csv")
Dts.Variables["FileExist"].Value = 1;
}
catch
{
Dts.Variables["FileExist"].Value = 0;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
But even if the file exist with .dat extension, it is returning 0 and sending the alert.
Perhaps you meant to write...
if (FileExtension == ".DAT" || FileExtension == ".csv")
Otherwise it would never evaluate to true.
Also you probably want a loop of some kind, your current structure is trying to access all the files at once (and not even quite doing that)
filenames = Directory.GetFiles(#"C:\Input_Data\");
foreach(string filename in filenames)
{
string FileExtension = Path.GetExtension(filename);
if (FileExtension == ".DAT" || FileExtension == ".csv")
Dts.Variables["FileExist"].Value = 1;
}
Edit:
Based on what I think you are saying it sounds like you want FileExist to equal 1 only when it contains only DAT and CSV types and no other types, in that case you want to reverse the logic a bit.
filenames = Directory.GetFiles(#"C:\Input_Data\");
Dts.Variables["FileExist"].Value = 1;
foreach(string filename in filenames)
{
string FileExtension = Path.GetExtension(filename);
if (FileExtension != ".DAT" && FileExtension != ".csv")
Dts.Variables["FileExist"].Value = 0;
}

Categories