Thursday, March 5, 2009

Convert Word .doc files to .html using ASP.NET

Programatically converting Word DOCs to HTML

This article describes how to use ASP.NET 2 to convert documents in Word .doc format into .html documents. This is done using the built-in features of MS Word, via the COM object.

The reason for doing this was as follows: I wanted to allow users to upload files to my Intranet, through their browser, and make them available for other people to look at. But if they uploaded Word documents, only people with Word installed would be able to view them, causing problems for Mac & Linux users. So, I wanted to get my server to convert the .doc file into a .html file automatically, at the point when the file is uploaded. There was no way that I was going to reverse-engineer a Word doc and figure out how to convert it into html, so instead I used the built-in facility inside MS Word that does this for you. If you give it a Word doc, it will save a .html file, and a separate folder with all the necessary images in it, all linked properly to the html file. Yes, I admit it is an html file full of weird codes, but it does work, in fact very nicely.

How to do it

The first step is that you must have MS Word installed on the server where this ASP.NET page is going to be running. You then add a reference to your ASP.NET project, telling Visual Studio where to find the vital Word library. To do this:

  1. In Solution Explorer, right-click on your project root and select "Add Reference".
  2. Go to the COM tab and find Microsoft Word 11 Object Library.
  3. Click on it and then click OK.

Once you have done this, you will be able to use the "Word" namespace in your project.

To test it, make a sample webpage, perhaps called test.aspx, and put a FileUpload, a Button and a Label on it. The FileUpload component is used to upload the file; the Button is clicked to make the process start, and the Label is used to display a success message.

The complete code for the upload routine is here:

protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
// When we click Button1, the file we specify is uploaded to a temporary
// folder, then converted into an html document...
string folder_to_save_in = @"c:\temp\documents\";
string filePath = folder_to_save_in + FileUpload1.FileName;
// This bit does the actual file upload:
FileUpload1.SaveAs(filePath);

// Here we set up a WOrd Application...
Word.ApplicationClass wordApplication = new Word.ApplicationClass();

// Opening a Word doc requires many parameters, but we leave most of them blank...
object o_nullobject = System.Reflection.Missing.Value;
object o_filePath = filePath;
Word.Document doc = wordApplication.Documents.Open(ref o_filePath,
ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject,
ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject,
ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject);

// Here we save it in html format...
// This assumes it was called "something.doc"
string newfilename = folder_to_save_in + FileUpload1.FileName.Replace(".doc", ".html");
object o_newfilename = newfilename;
object o_format = Word.WdSaveFormat.wdFormatHTML;
object o_encoding = Microsoft.Office.Core.MsoEncoding.msoEncodingUTF8;
object o_endings = Word.WdLineEndingType.wdCRLF;
// Once again, we leave many of the parameters blank.
// See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbawd11/html/womthSaveAs1_HV05213080.asp
// for full list of parameters.
wordApplication.ActiveDocument.SaveAs(ref o_newfilename, ref o_format, ref o_nullobject,
ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject, ref o_nullobject,
ref o_nullobject, ref o_nullobject, ref o_encoding, ref o_nullobject,
ref o_nullobject, ref o_endings, ref o_nullobject);

// Report success...
Label1.Text = "Uploaded successfully!";
// Finally, close original...
doc.Close(ref o_nullobject, ref o_nullobject, ref o_nullobject);
}
}

And that is it really. When you browse to a file and click the upload button, the file is uploaded to your server and stored in the temp folder. Then, this doc file is opened, and a SaveAs performed. This saves the new .html file in the same temp folder, with the associated image files in a subfolder with the same name as the .html file, but with _files appended to its name.

Sunday, March 1, 2009

DateTimePicker in datagridview using C#

If you want to add datetimepicker in datagridview then you have to create a custom control and its very easy.

If you create a seperate project and then you can use the dll in you future projects.

I have given the code just copy and past your project. Make it as seperate project then simply by adding the dll you can do it.

Step 1: Create a project name: datetimePicker_gridview

Step 2: Create the CalendarCell class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace datetimePicker_gridview
{
class CalendarCell : DataGridViewTextBoxCell
{

public CalendarCell(): base()
{
// Use the short date format.
this.Style.Format = "dd MMM yy";
}

public override void InitializeEditingControl(int rowIndex, object
initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue,dataGridViewCellStyle);
CalendarEditingControl ctl =DataGridView.EditingControl as CalendarEditingControl;
try
{
if (this.Value != DBNull.Value)
ctl.Value = (DateTime)this.Value;
}
catch (Exception err) { }
}

public override Type EditType
{
get
{
// Return the type of the editing contol that CalendarCell uses.
return typeof(CalendarEditingControl);
}
}

public override Type ValueType
{
get
{
// Return the type of the value that CalendarCell contains.
return typeof(DateTime);
}
}

public override object DefaultNewRowValue
{
get
{
// Use the current date and time as the default value.
return "";///DateTime.Now;
}
}

}
}


Step 3: Create the CalendarColumn class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Windows.Forms;

namespace datetimePicker_gridview
{
public class CalendarColumn : DataGridViewColumn
{
public CalendarColumn(): base(new CalendarCell())
{
}

public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
// Ensure that the cell used for the template is a CalendarCell.
if (value != null && !value.GetType().IsAssignableFrom(typeof(CalendarCell)))
{
throw new InvalidCastException("Must be a CalendarCell");
}
base.CellTemplate = value;
}
}

}
}


Step 4: Create the CalendarEditingControl class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace datetimePicker_gridview
{
class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
{
DataGridView dataGridView;
private bool valueChanged = false;
int rowIndex;

public CalendarEditingControl()
{
this.Format = DateTimePickerFormat.Short;
}

// Implements the IDataGridViewEditingControl.EditingControlFormattedValue
// property.
public object EditingControlFormattedValue
{
get
{
return this.Value.ToShortDateString();
}
set
{
if (value is String)
{
this.Value = DateTime.Parse((String)value);
}
}
}

// Implements the
// IDataGridViewEditingControl.GetEditingControlFormattedValue method.
public object GetEditingControlFormattedValue(
DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}

// Implements the
// IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
public void ApplyCellStyleToEditingControl(
DataGridViewCellStyle dataGridViewCellStyle)
{
this.Font = dataGridViewCellStyle.Font;
this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
}

// Implements the IDataGridViewEditingControl.EditingControlRowIndex
// property.
public int EditingControlRowIndex
{
get
{
return rowIndex;
}
set
{
rowIndex = value;
}
}

// Implements the IDataGridViewEditingControl.EditingControlWantsInputKey
// method.
public bool EditingControlWantsInputKey(
Keys key, bool dataGridViewWantsInputKey)
{
// Let the DateTimePicker handle the keys listed.
switch (key & Keys.KeyCode)
{
case Keys.Left:
case Keys.Up:
case Keys.Down:
case Keys.Right:
case Keys.Home:
case Keys.End:
case Keys.PageDown:
case Keys.PageUp:
return true;
default:
return !dataGridViewWantsInputKey;
}
}

// Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit
// method.
public void PrepareEditingControlForEdit(bool selectAll)
{
// No preparation needs to be done.
}

// Implements the IDataGridViewEditingControl
// .RepositionEditingControlOnValueChange property.
public bool RepositionEditingControlOnValueChange
{
get
{
return false;
}
}

// Implements the IDataGridViewEditingControl
// .EditingControlDataGridView property.
public DataGridView EditingControlDataGridView
{
get
{
return dataGridView;
}
set
{
dataGridView = value;
}
}

// Implements the IDataGridViewEditingControl
// .EditingControlValueChanged property.
public bool EditingControlValueChanged
{
get
{
return valueChanged;
}
set
{
valueChanged = value;
}
}

// Implements the IDataGridViewEditingControl
// .EditingPanelCursor property.
public Cursor EditingPanelCursor
{
get
{
return base.Cursor;
}
}

protected override void OnValueChanged(EventArgs eventargs)
{
// Notify the DataGridView that the contents of the cell
// have changed.
valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnValueChanged(eventargs);
}

}
}


Now Just create a form and test it.

private DataGridView dataGridView1 = new DataGridView();

public Form1()
{
InitializeComponent();

this.Controls.Add(this.dataGridView1);
this.Load += new EventHandler(Form1_Load);
this.Text = "DataGridView calendar column ";
}

private void Form1_Load(object sender, EventArgs e)
{
CalendarColumn col = new CalendarColumn();
col.HeaderText = "Date";
this.dataGridView1 .Columns.Add(col);
this.dataGridView1 .RowCount = 5;
foreach (DataGridViewRow row in this.dataGridView1 .Rows)
{
row.Cells[0].Value = DateTime.Now;
}
}


Thats all. Now use it.


One more thing you can do. when you are create the datagridview after createing and binding with dataSet

1. Click on CodeView in your form (which containig datagridview)
2. got to InitializeComponent();
3. Change your desire column type from System.Windows.Forms.DataGridViewTextBoxColumn to datetimePicker_gridview.CalendarColumn

No check it.

Thanks

Thursday, February 26, 2009

Generate SQL Server 2000 Script from 2005

How to Downgrade a Database from SQL Server 2005 to SQL Server 2000

As you may all know, SQL Server 2005 request a minimum of 8GB RAM to work… let say satisfactorily. I first didn’t knew that and after a while from the upgrade I did from SQL Server 2000 to 2005 my SQL Services were starting to crash three or four times per DAY!!!

At first I thought I was being attacked, but soon I realized it was nothing like that. I then decided to downgrade to an SQL Server 2000 edition. Though I looked around the internet to find some information on how to do that, I got very disappointed when I realized that no actual documentation of any kind could be found for that. So I am posting this thread to inform you on the procedures I had to follow for this action.

Before beginning I must assume, firstly that the user, who will attempt such thing, has a basic knowledge of SQL Environment, secondly that he has the two versions already installed (both 2000 and 2005), that a basic backup of the databases has been created and finally that all the 2005 SQL Server Users have been created at the SQL Server 2000 environment as well.

Step 1 Generating Scripts for the Database Elements and Structures

1) Right-click over the desired Database at 2005, Choose Tasks and the Generate Scripts (Option).

2) At the pop-up Dialog Box click at the Script All Objects in the selected Databases check box, to activate it and then Click the Next Button.

3) Set the following Elements to the following Values

a. Script Collation , set to TRUE

b. Script Database Create, set to TRUE

c. Script of SQL Version, set to SQL SERVER 2000

d. Script foreign keys, set to FALSE

e. Script Triggers, set to FALSE

Then Hit the Next button

4) Select the way the generated scripts should be saved (There are different selections. The most common one is Clipboard). Finally click the Next button till you reach the end.

5) Click Finish

After completing this procedure, we have to move to the SQL SERVER 2000 environment. Here, by using the Query Analyzer, we will have to run the scripts that were generated using the master database. Copy and Paste the script at the Query Analyzer and run it. After that the Structure of the Database will be created.

Be careful, the SQL Server 2005 Edition inserts the Views in a random place through the script. Therefore, all the scripts that are referred to the Views MUST be moved to the end of the script. If the Query Analyzer shows some errors do not be bothered. Delete all the elements created from the script and after you fix the code run it again.

Step2 Moving the data from 2005 to 2000

1) After completing the previous step successfully, moving the data follows. Right-click at the 2005 database you used to run the previous step and select Tasks and then choose the Export Data (option).

2) From the pop-up Dialog Box, select the Source Db and Click at the Next Button.

3) At the next step you will have to choose the destination server and the destination Database for the Data to be exported. Then Click Next.

4) A List of all the Source Database’s Elements will appear in the screen. Select one by one all the Elements you wish to move and for each one click at the button Edit Mappings (Located at the bottom right corner of the Dialog Box just under the Elements list). A new Dialog box will pop-up. Select the Delete rows in Destination Tables option and activate the Enable Identity Insert Option. (Remember to repeat this action for each of the selected Element from the list that will be moved.

CAUTION!!! A malfunction of the SQL Server 2005 has been found. Not sure why, after multiple tries I have observed that when I tried to move more than twelve Elements at once, the Export Data Wizard of SQL Server 2005 seemed to disable the Enable Identity Insert Option that was activated over the Edit Mappings Dialog Box. But if the number of the selected Elements is smaller than 12 no problem seemed to appear.

Step 3 Generating Scripts for the Database Foreign Keys and Triggers

Finally, to successfully finish the downgrade of the Database, the Triggers and the Foreign Keys of the DB must be produced. The procedure that should be followed is the one stated next:

1) Right-Click at the SQL 2005 Database and Select from Tasks Menu the Generate Scripts Option.

2) Using the pop-up Dialog Box make sure that the check box Script All Objects in the selected Databases is not enabled and hit the Next Button.

3) Set all the Elements on the List to a False Value except the ones that follow:

a. Include IF NOT EXISTS , set to TRUE

b. Script Owner, set to TRUE

c. Script of SQL Version, set to SQL SERVER 2000

d. Script foreign keys, set to TRUE

e. Script Triggers, set to TRUE

Then Hit the Next button

4) After finishing reading the Elements of the Database, a new list will appear at the Dialog Box. Make sure that you select ONLY THE TABLES of the Database and hit the Next Button.

5) At the screen that follows hit the Select All button and the Next.

6) Select the way the generated scripts should be saved (There are different selections. The most common one is Clipboard). Finally click the Next button till you reach the end.

7) Click Finish Button.

After completing this procedure, we have to move to the SQL SERVER 2000 environment. Here, by using the Query Analyzer, we will have to run the scripts that were generated using the master database. Copy and Paste the script at the Query Analyzer and run it. After that the Foreign Keys and the Triggers of the Database will be created.

After these steps the database should be fully functional under the SQL Server 2000 edition.