Click here to Skip to main content
Click here to Skip to main content

RESX to XLS conversion for multi-language support

, 25 Jul 2007
Rate this:
Please Sign up or sign in to vote.
Easily convert your RESX projects files to Excel and back to localized RESX

Resx2Xls ScreenShot

Introduction

Do you need to localize your RESX files and don't want to open them one file at a time, clean them of unused keys, localize them etc., etc.? Then Resx2Xls is for you.

  1. Open Resx2xls. Click on "Create new Excel document...," select your Project Root and follow the wizard. Done!!
  2. Fill your Excel file with your localized key values or just send it to your translator.
  3. Now, do you want to create the localized RESX files from the filled Excel workbook? Open Resx2xls, click on "Generate resx files...," select your Excel file, click Next and then click Finish. Done!!
  4. Have you updated your project after your resource files were modified/added/removed/updated? No problem. Open Resx2xls, click on "Update your Excel document...," click Next, select your Project Root and Excel document and click Finish. Done!!

Thanks go to Manish Ranjan Kumar and his WizardBase control. It has helped me to give the application a more decent style.

Background

I was frustrated with copying my project resource files created in VS 2005, cleaning them of unused keys and then localizing them one file at a time. This tool should help you to just point and click at your project and obtain an Excel file filled with all of the strings of ALL of your resource files. After compiling the XLS with the translations, I wanted to convert all of the keys back into localized RESX files. I hope this helps!

Points of interest

I've had some problems loading resources with the ResxResourceReader class. I've noticed that if you have an image resource stored in the resource file, the path of the image in the XML document is relative to the document itself, not the project. Opening from another directory, i.e. Resx2xls bin, I get a "cannot parse" path exception. This was solved by setting the BasePath property of the resource reader with the path to the RESX file.

History

  • 25-7-2007: Article edited and posted to the main CodeProject article base
  • 5-7-2007: Added wizard
  • 4-7-2007: First release

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Marco Roello
Web Developer
Italy Italy
No Biography provided

Comments and Discussions

 
GeneralRe: License Pinmembermatmat19823516-Sep-10 14:16 
GeneralIt works great but... Pinmemberpatokike8-Oct-09 4:27 
GeneralIdentifying unused string keys Pinmembertrinity7917-Sep-09 7:56 
Generalexisting translations PinmemberPatrick Mortara11-Aug-09 23:29 
GeneralRe: existing translations Pinmemberjaxwax16-Oct-09 10:58 
GeneralRe: existing translations PinmemberPatrick Mortara16-Oct-09 12:06 
Questionno comments? Pinmemberkevin.floyd17-Dec-08 13:15 
GeneralProblem with App_LocalResources - extra files Pinmemberuswebpro230-Sep-08 22:38 
Hello,
I found this program works great with the GlobalResources, however with the App_LocalResources, it creates duplicated files for each language. If you have the same problem, check out the script below. I put it on the web form + wire it to a button click, and it deletes the extra files and keeps the ones you need. - Yes I know this is a cheap "band aid solution" but its quick and worked 4 me.
 
public partial class Temp_RemoveBadLocalFiles : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
 
}
protected void Button1_Click(object sender, EventArgs e)
{
string folder = @"C:\Users\aron\Documents\Visual Studio 2008\WebSites\TheaterSalesCorporate\App_LocalResources\";
Label1.Text = TraverseTree(folder);

}
 
public string TraverseTree(string root)
{
StringBuilder sb = new StringBuilder();
 
// Data structure to hold names of subfolders to be
// examined for files.
Stack dirs = new Stack(20);
 
if (!System.IO.Directory.Exists(root))
{
throw new ArgumentException();
}
dirs.Push(root);
 
while (dirs.Count > 0)
{
string currentDir = dirs.Pop();
string[] subDirs;
try
{
subDirs = System.IO.Directory.GetDirectories(currentDir);
}
// An UnauthorizedAccessException exception will be thrown if we do not have
// discovery permission on a folder or file. It may or may not be acceptable
// to ignore the exception and continue enumerating the remaining files and
// folders. It is also possible (but unlikely) that a DirectoryNotFound exception
// will be raised. This will happen if currentDir has been deleted by
// another application or thread after our call to Directory.Exists. The
// choice of which exceptions to catch depends entirely on the specific task
// you are intending to perform and also on how much you know with certainty
// about the systems on which this code will run.
catch (UnauthorizedAccessException e)
{
sb.Append(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
sb.Append(e.Message);
continue;
}
 
string[] files = null;
try
{
files = System.IO.Directory.GetFiles(currentDir);
}
 
catch (UnauthorizedAccessException e)
{
 
sb.Append(e.Message);
continue;
}
 
catch (System.IO.DirectoryNotFoundException e)
{
sb.Append(e.Message);
continue;
}
// Perform the required action on each file here.
// Modify this block to perform your required task.
foreach (string file in files)
{
try
{
// Perform whatever action is required in your scenario.
System.IO.FileInfo fi = new System.IO.FileInfo(file);
if ((fi.Name.Substring(2, 1).Equals(".")) || ((fi.Name.Substring(0, 6).Equals("zh-CHS"))))
{
sb.AppendFormat("DELETED FILE: {0}: {1}, {2}
", fi.Name, fi.Length, fi.CreationTime);
fi.Delete();
}
else
{
sb.AppendFormat("GOOD FILE: {0}: {1}, {2}
", fi.Name, fi.Length, fi.CreationTime);
}
}
catch (System.IO.FileNotFoundException e)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()
// then just continue.
sb.Append(e.Message);
continue;
}
}
 
// Push the subdirectories onto the stack for traversal.
// This could also be done before handing the files.
foreach (string str in subDirs)
dirs.Push(str);
}
 
return sb.ToString();
}
 
}
 
- aron

GeneralOttimo lavoro... PinmemberNicola Costantini21-Jan-08 5:59 
GeneralExcellent work PinmemberEthan Huang20-Sep-07 0:13 
GeneralRe: Excellent work Pinmemberumurlu1-Dec-08 22:05 
GeneralCOMException: Old format or invalid type library Pinmembermarco vervoort10-Jul-07 22:18 
GeneralRe: COMException: Old format or invalid type library PinmemberKerdal17-Jul-07 8:18 
GeneralRe: COMException: Old format or invalid type library Pinmembermarco vervoort17-Jul-07 22:16 
GeneralRe: COMException: Old format or invalid type library Pinmemberuswebpro218-Aug-08 3:09 
Generalresource editor with multi language support Pinmemberedwin_vermeer10-Jul-07 3:39 
GeneralRe: resource editor with multi language support PinmemberMarco Roello22-Jul-07 22:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141220.1 | Last Updated 25 Jul 2007
Article Copyright 2007 by Marco Roello
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid