As part of an ETL process I am importing data from a variety of different Excel files into a database. Before this happens I need to be able to change the cell format of all cells in an excel worksheet to be in the "General" format.
I have made a start but I'm afraid I dont know how to progress after this:
using Excel = Microsoft.Office.Interop.Excel;
.
.
.
String FilePath = "Code to get file location from database"
String SheetName = "Code to get SheetName from database"
Excel.Application MyApp = new Excel.Application();
MyApp.Visible = false;
Excel.Workbook myWorkbook = MyApp.Workbooks.Open(FilePath,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing);
//Code here to convert all rows to data type of general and then save
MyApp.Workbooks.Close();
Any help on this would be greatly appreciated
You can use Range.NumberFormat property:
var myWorksheet = (Excel.Worksheet)myWorkbook.Worksheets[1];
myWorksheet.Cells.NumberFormat = "General";
Please note that this may cause problems if your sheet contains date values.
Related
I need to convert an XLSX file to another CSV file.
I've done a lot of research on how to do this process, but I did not find anything that suited me.
I found this Github Gist only Convert an Epplus ExcelPackage to a CSV file
That returns an Array of binary. But apparently it does not work any more.
I'm trying to load Array using LoadFromCollection
FileInfo novoArquivoCSV = new FileInfo(fbd.SelectedPath);
var fileInfoCSV = new FileInfo(novoArquivo + "\\" + nameFile.ToString() + ".csv");
using (var csv = new ExcelPackage(fileInfoCSV))
{
csv.Workbook.Worksheets.Add(nameFile.ToString());
var worksheetCSV = csv.Workbook.Worksheets[1];
worksheetCSV.Cells.LoadFromCollection(xlsx.ConvertToCsv());
}
The code you linked to reads an XLSX sheet and returns the CSV data as a byte buffer through a memory stream.
You can write directly to a file instead, if you remove the memory stream and pass the path to the target file in ConvertToCsv :
public static void ConvertToCsv(this ExcelPackage package, string targetFile)
{
var worksheet = package.Workbook.Worksheets[1];
var maxColumnNumber = worksheet.Dimension.End.Column;
var currentRow = new List<string>(maxColumnNumber);
var totalRowCount = worksheet.Dimension.End.Row;
var currentRowNum = 1;
//No need for a memory buffer, writing directly to a file
//var memory = new MemoryStream();
using (var writer = new StreamWriter(targetFile,false, Encoding.UTF8))
{
//the rest of the code remains the same
}
// No buffer returned
//return memory.ToArray();
}
Encoding.UTF8 ensures the file will be written as UTF8 with a Byte Order Mark that allows all programs to understand this is a UTF8 file instead of ASCII. Otherwise, a program could read the file as ASCII and choke on the first non-ASCII character encountered.
Checkout the .SaveAs() method in Excel object.
wbWorkbook.SaveAs("c:\yourdesiredFilename.csv", Microsoft.Office.Interop.Excel.XlFileFormat.xlCSV)
Or following:
public static void SaveAs()
{
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.ApplicationClass();
Microsoft.Office.Interop.Excel.Workbook wbWorkbook = app.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel.Sheets wsSheet = wbWorkbook.Worksheets;
Microsoft.Office.Interop.Excel.Worksheet CurSheet = (Microsoft.Office.Interop.Excel.Worksheet)wsSheet[1];
Microsoft.Office.Interop.Excel.Range thisCell = (Microsoft.Office.Interop.Excel.Range)CurSheet.Cells[1, 1];
thisCell.Value2 = "This is a test.";
wbWorkbook.SaveAs(#"c:\one.xls", Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wbWorkbook.SaveAs(#"c:\two.csv", Microsoft.Office.Interop.Excel.XlFileFormat.xlCSVWindows, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wbWorkbook.Close(false, "", true);
}
Is there any simple way to convert .xls file to .csv file? (Excel)
There are several other resources online that can help with this ind of thing. Actually, for something generic like this, you should always Google for a solution, and try to figure it out yourself. That's the best way to learn how to do technical things. If you get stuck, or if you have a very specific question, this site is a great place to post your question(s). It seems to me, you probably started here, and you didn't do any preliminary work yourself.
I am using the below piece of code to add hyperlink to a given cell("A1" here):
Workbook workbook = _excelApp.Workbooks.Open("C:\\temp\\test1.xlsx",
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Worksheet worksheet = (Worksheet)workbook.Worksheets[1];
Range rangeToHoldHyperlink = worksheet.get_Range("A1", Type.Missing);
string hyperlinkTargetAddress = "www.bing.com";
Range excelRange = worksheet.UsedRange;
object[,] valueArray = (object[,])excelRange.get_Value(
XlRangeValueDataType.xlRangeValueDefault);
worksheet.Hyperlinks.Add(
rangeToHoldHyperlink,
hyperlinkTargetAddress,
string.Empty,
string.Empty,
valueArray[1, 1].ToString());
It adds the hyperlink. But, on clicking it, it says:
Reference not valid
On hovering the mouse over cell text, it displays the hyperlink as:
excel_file_path\hyperlinkTargetAddress
Why it is doing so?
How this can be overcome?
You can add different types of hyperlinks. By default, Excel assumes that you want to link a file in your hard drive (in the folder where the spreadsheet it). To tell Excel that you want a website, you have to write the full address (with the starting http:// bit).
string hyperlinkTargetAddress = "http://www.bing.com";
I have a program that I need to maintain ( was not written by me)
What the actual function is doing is that it gets an excel file from the internet and then convert it to html (I don't even know why) then it tries to save it into a new csv file...
Long story short, my problem in the whole code resides in these 2 parts
xl = new Microsoft.Office.Interop.Excel.Application();
xl.Visible = false;
//p_sUBKPath is the path of the HTML file that has the converted excel file
Microsoft.Office.Interop.Excel.Workbook workbook = xl.Workbooks.Open(p_sUBKPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range range = ws.UsedRange;
object[,] values = (object[,])range.Value2;
The code has an if statement that try to ensure that every values from the first row in the html matches values required
if (Convert.ToString(values[1, 1]).ToUpper().Trim() == "DOMAIN NAME" && values[1, 2]).ToUpper().Trim() == "SHORT NAME" && values[1,3]).ToUpper().Trim() == "LONG NAME" )
{
//do something
}
The if statement is returning true and jumping to else statement, after few debugging and trying some lines of code it turned out that values[1,2] and values[1,3] are returning out of array boundary error.
and the value of values[1,1] is the whole row which contains DOMAIN NAME, SHORT NAME, AND LONG NAME, so even this statement returns flase
if (Convert.ToString(values[1, 1]).ToUpper().Trim() == "DOMAIN NAME")
{
//do something
}
Any idea what is happening in the code?
A really good new feature of Excel 2013 is that it cannot forced to show more than one Excel workbook in one application. This seems the cause of my Problem:
If I open an Excel workbook programmatically using c# and interop Excel 2013 starts with a new application window. I can working with the workbook in code without problems but I want to hide the application.
Using
Excel.Application excelApp = new Excel.Application();
......
excelApp.Workbooks.Open(...);
excelApp.Visible = false;
hides the application window after showing it. Is there a way to stop showing the application as in Excel 2010 or earlier Version?
In my Excel 2013, using excelApp = new Excel.Application doesn't show any window.
May it be some VBA code in opened workbook which displays window?
So I know the question is old but I needed an answer and none of the given ones worked for me. I ended up just setting Visible to false when initializing to avoid the window flashing open before hiding.
Excel.Application excelApp = new Excel.Application() { Visible = false };
Hide Excel application your code has launched, before opening any Workbook :
Excel.Application excel = new Excel.Application();
excel.Visible = false;
[...]
Excel.Workbook workbook;
workbook = excel.Workbooks.Open(...);
You should always put the Visible into try/catch-block
Excel.Application xlsApp = new Excel.Application();
try
{
// Must be surrounded by try catch to work.
// http://naimishpandya.wordpress.com/2010/12/31/hide-power-point-application-window-in-net-office-automation/
xlsApp.Visible = false;
xlsApp.DisplayAlerts = false;
}
catch (Exception e)
{
Console.WriteLine("-------Error hiding the application-------");
Console.WriteLine("Occured error might be: " + e.StackTrace);
}
Excel.Workbook workbook;
workbook = xlsApp.Workbooks.Open(File, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
I have a Excel File, i am able to read single row from "Excel file" Cell by Cell and store it in a ArrayList.
ExcelRange reads one row at a time , stores it into ArrayList (arrForValues).
ExcelRange = ExcelWorkSheet.get_Range("A"+rowNumber,columnMaxName+rowNumber );
items = (object[,])ExcelRange.Value2;
for (int i = 1; i <= nColumn; i++)
{
arrForValues.Add(items[1, i]);
}
I want to write row to another Excel file.There is some condition which needs to be satisfied for "particular Row" to get selected for writing.
Is there any way i can write complete ArrayList("Single Row") to ExcelFile instead of Cell By Cell Wrinting.
Thanks in Advance.
You can write whole array of objects by using range's set_value method
Here is example:
class Program
{
static void Main(string[] args)
{
string file = AppDomain.CurrentDomain.BaseDirectory + "SetArrayToExcel.xlsx";
Excel.Application excelApp = new Excel.Application();
excelApp.Visible = true;
Excel.Workbook wb = excelApp.Workbooks.Open(file, Type.Missing, Type.Missing
, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing
, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing
, Type.Missing, Type.Missing);
object[,] testTable = new object[2, 2]{{"6-Feb-10", 0.1}, {"26-Mar-10", 1.2}};
Excel.Worksheet ws = wb.ActiveSheet as Excel.Worksheet;
Excel.Range rng = ws.get_Range("rngSetValue", Type.Missing);
//rng.Value2 = testTable;
rng.set_Value(Type.Missing, testTable);
}
}
I highly recommend just getting FlexCel. It's fairly cheap and it has methods for copying rows and columns.
EDIT: I see that you mean to copy between workbooks. It's still easier with FlexCel than COM or the Interop stuff.
I do some writing to Excel in some code I have. The only way I have found to do it is with a foreach to iterate through my list of values and using an indexer to keep track of what cell it is going into. You might investigate the Range class and the Cells property:
http://msdn.microsoft.com/en-US/library/microsoft.office.tools.excel.namedrange.cells(v=vs.80).aspx
It didn't work for what I am doing but it might for you.
Another alternative would be to merge the cells in a range, build a string of all the values in your array and set the merged range value equal to that string but that might not be what you want.