Do C# NPOI support phonetic text (japanese/chinese text)? - c#

I am converting excel file .xlsx with phonetic text (Japanese text) but the output file gives out warning that there are unreadable contents, and the data are missing from the file.
It seems that the issues were because NPOI can't process the phonetic guide from Microsoft Excel in Japanese language.
This only applies on .xlsx files and not .xls files.
I'm not sure how to attach the sample excel file but the image above shows what it looks like. Basically, if you use Microsoft Excel in Japanese version, there will be automatic phonetic guide for every kanji (Chinese character).
public void writeoutput(string val)
{
try
{
IWorkbook book;
string outPath = "<path for input file>";
using (FileStream file = new FileStream(outPath, FileMode.Open, FileAccess.Read))
{
try
{
book = new XSSFWorkbook(file);
}
catch (Exception e)
{
book = null;
}
if (book == null)
{
book = new HSSFWorkbook(file);
}
file.Close();
}
//ISheet sheet = outputSheet.GetSheet("Sheet1");
ISheet sheet = book.GetSheetAt(0);
sheet.CopySheet("NewSheet", false);
IRow dataRow = sheet.GetRow(35) ?? sheet.CreateRow(35);
ICell cell = dataRow.GetCell(8) ?? dataRow.CreateCell(8);
cell.SetCellValue(val);
//File.Delete(outPath);
outPath = "<path for output file>";
using (FileStream file = new FileStream(outPath, FileMode.OpenOrCreate, FileAccess.Write))
{
book.Write(file);
file.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
textBox2.Text = "done";
}
}
I tried disable the phonetic guide in Microsoft Excel and the processing of the .xlsx file works with no issues but I can only disable the phonetic guide on the text one by one and it is very time consuming.

Related

Openxml - Embedded excel corrupts ppt

Powerpoint shows "Unable to read an object" after I embed the excel into powerpoint file via openxml.
Am using a simple excel with a chart and a pptx created already.
This fails in both .NetCore and .NetFramework
Here is my code.
string PPTFileName = #"c:\tmp\Example04.pptx";
string spreadsheetFileName = #"c:\tmp\demoOut5.xlsx";
using (PresentationDocument myPresDoc = PresentationDocument.Open(PPTFileName, true))
{
SlidePart slidePartBookMark = null;
string chartPartIdBookMark = "";
foreach (var slidePart in myPresDoc.PresentationPart.SlideParts)
{
if (slidePart.ChartParts.Any())
{
slidePartBookMark = slidePart;
var chartPart = slidePart.ChartParts.First();
chartPartIdBookMark = slidePart.GetIdOfPart(chartPart);
slidePart.DeletePart(chartPart);
slidePart.Slide.Save();
break;
}
}
var newChartPart = slidePartBookMark.AddNewPart<ChartPart>(chartPartIdBookMark);
EmbeddedPackagePart embPackage = newChartPart
.AddNewPart<EmbeddedPackagePart>("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "rId1");
embPackage.FeedData(new FileStream(#"c:\tmp\demoOut4.xlsx", FileMode.Open, FileAccess.Read));
DocumentFormat.OpenXml.Drawing.Charts.ExternalData ed = new DocumentFormat.OpenXml.Drawing.Charts.ExternalData();
ed.Id = "rId1";
slidePartBookMark.Slide.Save();
myPresDoc.Close();
Console.WriteLine("Done");
Console.ReadKey();
}
Any help or direction would be appreciated. Thanks.

Error message wile trying to open .xls file

I am creating an excel file on the fly for sending it an an attachment in an email. The relevant code snippet is provided below (It's a console app)
public static void SendEmailWithExcelAttachment(DataTable dt)
{
try
{
string smptHost = smptTuple.Item1;
MailMessage mailMsg = new MailMessage();
.............................................
.............................................
byte[] data = GetData(dt);
//save the data to a memory stream
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
mailMsg.Attachments.Add(new System.Net.Mail.Attachment(ms, attachmentName, "application/vnd.ms-excel"));
....................................
....................................
//send email
smtpClient.Send(mailMsg); }
catch (Exception ex)
{
throw ex;
}
}
private static byte[] GetData(DataTable dt)
{
string strBody = DataTable2ExcelString(dt);
byte[] data = Encoding.ASCII.GetBytes(strBody);
return data;
}
private static string DataTable2ExcelString(System.Data.DataTable dt)
{
string excelSheetName = "Sheet1";
StringBuilder sbTop = new StringBuilder();
sbTop.Append("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" ");
sbTop.Append("xmlns=\" http://www.w3.org/TR/REC-html40\"><head><meta http-equiv=Content-Type content=\"text/html; charset=windows-1252\">");
sbTop.Append("<meta name=ProgId content=Excel.Sheet ><meta name=Generator content=\"Microsoft Excel 9\"><!--[if gte mso 9]>");
sbTop.Append("<xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>" + excelSheetName + "</x:Name><x:WorksheetOptions>");
sbTop.Append("<x:Selected/><x:ProtectContents>False</x:ProtectContents><x:ProtectObjects>False</x:ProtectObjects>");
sbTop.Append("<x:ProtectScenarios>False</x:ProtectScenarios></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets>");
sbTop.Append("<x:ProtectStructure>False</x:ProtectStructure><x:ProtectWindows>False</x:ProtectWindows></x:ExcelWorkbook></xml>");
sbTop.Append("<![endif]-->");
sbTop.Append("</head><body><table>");
string bottom = "</table></body></html>";
StringBuilder sbHeader = new StringBuilder();
//Header
sbHeader.Append("<tr>");
for (int i = 0; i < dt.Columns.Count; i++)
{
sbHeader.Append("<td>" + dt.Columns[i].ColumnName + "</td>");
}
sbHeader.Append("</tr>");
//Items
for (int x = 0; x < dt.Rows.Count; x++)
{
sbHeader.Append("<tr>");
for (int i = 0; i < dt.Columns.Count; i++)
{
sbHeader.Append("<td>" + dt.Rows[x][i] + "</td>");
}
sbHeader.Append("</tr>");
}
string data = sbTop.ToString() + sbHeader.ToString() + bottom;
return data;
}
This works but when I tried to open the excel file from the attachement, I receive:
I checked an found some solution in SO Post but could not make it to work. I tried like <x:DisplayAlerts>False</x:DisplayAlerts> but didn't work.
If the file you want to create and send doesn't have to be in exactly ".xls" format.. and if you are comfortable with ".xlsx" format... I think you might wanna try with EPPlus library, as it was mentioned Here. As I said you have to work with ".xlsx" (you can work with other excel formats but you'll get the same message about the file format when you open the file). So you can create the Excel file in temp folder with EPPlus using the DataTable as sorce and send the temp file by email... something like this for example:
public static void SendEmailWithExcelAttachment(DataTable dt)
{
try
{
string smptHost = smptTuple.Item1;
MailMessage mailMsg = new MailMessage();
string temp = Path.GetTempPath(); // Get %TEMP% path
string file = "fileNameHere.xlsx";
string path = Path.Combine(temp, file); // Get the whole path to the file
FileInfo fi = new FileInfo(path);
using (ExcelPackage pck = new ExcelPackage(fi))
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Table");
ws.Cells["A1"].LoadFromDataTable(dt, true);
pck.Save();
}
mailMsg.Attachments.Add(new System.Net.Mail.Attachment(path, "application/vnd.ms-excel"));
try
{
//send email
smtp.Send(mailMsg);
}
catch (Exception)
{
//do smth..
}
finally
{
File.Delete(path);
}
}
catch (Exception ex)
{
throw ex;
}
}
I created a simple DataTable, sent it to myself in ".xlsx" format and was able to open it without any "Format warnings". I hope that helps.
The warning is display by MS Excel application because your file is not a real Excel file. It is an HTML with XLS extension. An XLS file is a binary file. MS Excel recognizes the HTML file and it display the file in its spreadsheet grid.
MS Excel displays security warnings for files that comes from external sources like email or internet.
The best solution is to use an Excel library that saves real Excel files in xls (old Excel file format) or xlsx (new Excel file format).
You can choose between free libraries like NPOI, EPPlus or commercial libraries like EasyXLS. Some of them saves only xls files, other only xlsx files and a few of them supports both file formats.
Solution to the warning / error “The file you are trying to open is in a different format than specified by the file extension”
Cause :
This happens because in the traditional Export to Excel method, the GridView is first converted to an HTML string and then that HTML string is exported to Excel. Thus originally it is not an Excel file hence the Excel Application throws the warning / error “The file you are trying to open is in a different format than specified by the file extension”.
Solution :
The solution to this problem is using ClosedXML library which is wrapper over the DocumentFormat.OpenXml library.
Dependency : OpenXml SDK 2.0 must be installed in system
You can get more help here :)

Print excel file to pdf in landscape mode using C#

I have a project that it should print check bill in both excel and pdf format.
Originally I use NPOI to print excel and Spire to print pdf using the excel file:
public HSSFWorkbook Workbook;
public void SaveExcelFile(string FilePath)
{
this.AutoSizeColumn();
FilePath = FilePath == "" ? AppDomain.CurrentDomain.BaseDirectory + "sample.xls" : FilePath;
var File = new FileStream(FilePath, FileMode.Create);
Workbook.Write(File);
File.Close();
}
public void SavePdfFileFromExcel(string ExcelFilePath, string PdfFilePath)
{
Workbook pdfWorkbook = new Workbook();
pdfWorkbook.LoadFromFile(ExcelFilePath);
pdfWorkbook.SaveToFile(PdfFilePath, Spire.Xls.FileFormat.PDF);
}
But Spire will just print the pdf in portrait, and the bill will look small and ugly. I want to know if there's a way I can print the pdf in landscape.
Or I should use iText to create a pdf format by self?
Try like this:
public void ExcelLandscapeFormat()
{
try
{
((Microsoft.Office.Interop.Excel._Worksheet)
excelWbook.ActiveSheet).PageSetup.Orientation =
Microsoft.Office.Interop.Excel.XlPageOrientation.xlLandscape;
excelWbook.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF,
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + output);
}
catch
{ }
}

Excel files are corrupted when retrieved from SQL DB

I am working with a SQL DB that stores Excel files (along with other file types such as PDF) as binary data. I use the following code to extract these files onto the file system.
The Problem:
PDF files come out just fine. But for Excel, the files get created and when I try to open them, they crash or just give me garbage text.
I am using this code from the previous guy who wrote this app for retrieving files. This code uses OpenMcdf which I don't fully understand because I couldn't find useful online documentation for it.
//execution starts here
public override void SaveToDisk()
{
byte[] keys = { (byte)0xd0, (byte)0xcf };
//Searches through m_RawOleObject for combination of 'keys'
int offset = Utils.SearchBytes(m_RawOleObject, keys); //returns '60' in case of Excel and '66' in case of Pdf
//m_RawOleOjbect contains the data from the sqlDataReader (the binary data from the column.)
m_RawOleObject = strip(m_RawOleObject, offset);
MemoryStream ms = new MemoryStream(m_RawOleObject);
CompoundFile cf = new CompoundFile(ms);
GetStorageByName(cf.RootStorage, m_StorageName);
if (Storage != null)
{
if (Storage is CFStream)
{
m_RawOleObject = (Storage as CFStream).GetData();
}
m_filename = System.IO.Path.Combine(STOREPATH, Utils.CombineFilenameWithExtension(Filename, m_extension));
WriteToFile(m_filename, m_RawOleObject);
}
}
protected void WriteToFile(string fn, byte[] obj)
{
fn = GetNextAvailableFilename(fn, 0);
FileStream fs = new FileStream(fn, FileMode.Create);
BinaryWriter writer = new BinaryWriter(fs);
writer.Write(obj);
writer.Close();
fs.Close();
fs.Dispose();
}
protected void GetStorageByName(CFStorage cfs, string name)
{
VisitedEntryAction va = delegate(CFItem target)
{
if (target is CFStorage)
{
GetStorageByName((CFStorage)target, name);
}
else
{
if (target.Name == name)
Storage = target;
}
};
//Visit NON-recursively (first level only)
cfs.VisitEntries(va, false);
}
Any ideas what's happening here? why are the excel corrupted? I couldn't find a lot online despite hours of search!
any ideas, suggestions, or solutions will be appreciated.
Thanks
Change your SaveToDisk logic as follows:
public override void SaveToDisk()
{
byte[] keys = { (byte)0xd0, (byte)0xcf, (byte)0x11, (byte)0xe0, (byte)0xa1, (byte)0xb1, (byte)0x1a, (byte)0xe1 };
int offset = Utils.SearchBytes(m_RawOleObject, keys);
using (MemoryStream ms = new MemoryStream(strip(m_RawOleObject, offset)))
{
CompoundFile cf = new CompoundFile(ms, UpdateMode.ReadOnly, true, true);
m_filename = GetNextAvailableFilename(System.IO.Path.Combine(STOREPATH, Utils.CombineFilenameWithExtension(Filename, m_extension)), 0);
using (var fs = new FileStream(m_filename, FileMode.Create))
{
cf.Save(fs);
cf.Close();
}
}
//Workbook would be saved as hidden in previous step
Microsoft.Office.Interop.Excel.Application xlApp = null;
Microsoft.Office.Interop.Excel.Workbook xlWb = null;
try
{
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWb = xlApp.Workbooks.Open(m_filename);
xlWb.CheckCompatibility = false;
foreach (Window wn in xlApp.Windows)
{
wn.Visible = true;
}
xlWb.Save();
xlWb.Close();
}
catch (Exception e)
{
//TODO: Log error and continue
}
finally
{
if (xlWb != null)
Marshal.ReleaseComObject(xlWb);
if (xlApp != null)
Marshal.ReleaseComObject(xlApp);
xlApp = null;
}
}

C# VS2005 Convert Pipe Delimited .TXT to Excel Workbook .XLS

I am using VS2005 C# and im trying to convert a pipe delimited text file to excel workbook format. Below is my code:
public partial class TextToExcel : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SaveAsExcelBtn_Click(object sender, EventArgs e)
{
string xlExtension = ".csv";
string strExcelOutputFilename = "C:/Documents and Settings/rhlim/My Documents/" + DateTime.Now.ToString("yyyyMMddHHmmss") + xlExtension;
// Before attempting to import the file, verify
// that the FileUpload control contains a file.
if (TextFile.HasFile)
{
// Get the name of the Excel spreadsheet.
string strFileName = Server.HtmlEncode(TextFile.FileName);
// Get the extension of the text.
string strExtension = Path.GetExtension(strFileName);
// Validate the file extension.
if (strExtension != ".TXT" && strExtension!=".txt")
{
Response.Write("<script>alert('Failed to import. Cause: Invalid text file.');</script>");
return;
}
// Generate the file name to save the text file.
//string strUploadFileName = "C:/Documents and Settings/rhlim/My Documents/Visual Studio 2005/WebSites/SoD/UploadFiles/" + DateTime.Now.ToString("yyyyMMddHHmmss") + strExtension;
using (StreamWriter outputWriter = new StreamWriter(File.Create(strExcelOutputFilename)))
{
StreamReader inputReader = new StreamReader(TextFile.FileContent);
string fileContent = inputReader.ReadToEnd();
fileContent = fileContent.Replace('|', ';');
outputWriter.Write(fileContent);
TextFile.SaveAs(strExcelOutputFilename);
inputReader.Close();
}
//string strExcelOutputFilename = "C:/Documents and Settings/rhlim/My Documents/" + DateTime.Now.ToString("yyyyMMddHHmmss")+xlExtension;
// Save the Excel spreadsheet on server.
//TextFile.SaveAs (strExcelOutputFilename);
}
else Response.Write("<script>alert('Failed to import. Cause: No file found');</script>");
}
}
Currently I am having some file saving errors
Any suggestions? Thanks a lot!
That's because Excel doesnt support pipelines you have to convert it so comma's or semicolumns like:
using (StreamWriter outputWriter = new StreamWriter(File.Create(strExcelOutputFilename)))
{
StreamReader inputReader = new StreamReader(TextFile.FileContent);
string fileContent = inputReader.ReadToEnd();
fileContent = fileContent.Replace('|', ',');
outputWriter.Write(fileContent);
}
I googled and hope it will help you: http://csharp.net-informations.com/excel/csharp-create-excel.htm
Or, already answered: Create Excel (.XLS and .XLSX) file from C#
At the first link, the line xlWorkSheet.Cell[x,y] to put element in the dedicated cell.
FYI, xlsx format(new from Office 2007) will give you a great manipulation capability with code.
For generating and manipulating excel files, I personally prefer the NPOI library. Download it from Codeplex, add reference to the NPOI dlls to your project. Store a “template” excel file you would like in a known location, with the any column headers/formatting that you need. Then you just use npoi to make a copy of the template file and manipulate it at a sheet/row/column level and put whatever data you want.
The sample code snippet looks something like this. Assuming you have split your input into a List of strings
const string ExcelTemplateFile = "~/Resources/ExcelInputTemplate.xls";
const string ExcelWorksheetName = "Output Worksheet";
const int RequiredColumn = 1;
private HSSFWorkbook CreateExcelWorkbook(IEnumerable<String> inputData)
{
FileStream fs = new FileStream(Server.MapPath(ExcelTemplateFile), FileMode.Open, FileAccess.Read);
// Getting the complete workbook...
HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs, true);
// Getting the worksheet by its name...
HSSFSheet sheet = templateWorkbook.GetSheet(ExcelWorksheetName);
int startRowIterator = 1;
foreach (string currentData in inputData)
{
sheet.CreateRow(startRowIterator).CreateCell(RequiredColumn).SetCellValue(currentData);
}
}

Categories