tags:

views:

523

answers:

5

We have an application in which admin members can add content for their subordinates to view. Their requirement is that it should be able to display word, excel, powerpoint and pdf documents in a non-editable manner.

The one option that I found for doing this is to have the content loaded into a web browser component. The downside to that is that it prompts the user to open/save/cancel. We are concerned that the subordinates, being mostly computer illiterate, will have trouble opening the documents in this manner.

Using the above method also means that Microsoft Office and Adobe Acrobat (or another IE enabled pdf viewer) need to be installed on all the machines that will be running the application, which implies expensive licensing fees.

Is there a better way to get this content to display on my forms in C#?

A: 

Have you looked at Microsoft Word 9.0 object library ? It might not be possible to just display the data as it was originally written, however, you COULD do something evul here, how about, printing as a temporary pdf in memory and displaying that?

This is how you display a PDF with C#

Filip Ekberg
Using this method to display PDF, Adobe Acrobat will have to be installed on the System.
Cyril Gupta
Adobe Acrobat is free and you can probably bundle it with your software, and tehre might be an SDK from adobe so you don't. I can't see the problems really, theres no licensing fees.
Filip Ekberg
This requires Adobe Acrobat, not Adobe Acrobat Reader. The reader is free, but Acrobat comes with a rather hefty charge.Using the Word object library, to the best of my knowledge, requires office to be installed on the machine.
RichieACC
A: 

All this is windows specific.

If you wish to display something on a client machine without relying on any local install then you must take total responsibility for the rendering either by:

  1. Supplying some sort of non invasive libraries that run at the client and know how to render it
  2. Use the 'proper' tools/libraries to render it on the server to an in memory image and send that image to the client. Slow, very computationally expensive on your server and will not provide a 'document like' interface to your clients.

Sumatra is completely free and open source. It would not require any form of install, thus including it in your application install as a binary in a sub folder and then shelling out directly to that to display pdf's will work fine (either the pdf ids network accessible so it's as simple as executing

SumatraPDF.exe {path-to-file}

If it is not network accessible download it in the background to a temporary location and then execute as above.

Office documents are a bit more tricky since they all require a local install. Here's a (out of date) list Note that many of the links to downloads will then point you to the very latest version which is recommended.

An alternate approach for this is to use OpenOffice.org in it's 'portable' incarnation which will allow it to run without requiring an install (so you can drop it in place just like the Sumatra approach) this however has a great many flaws in your case because it would still require java to be installed, the resulting fiels would be editable (unless you made changes to the OpenOffice version which may well be complex) and you may not get terribly good display.

If you have any sort of ability to run arbitrary programs on install of your application installing the viewers is probably for the best, they are entirely free and redistributable.

If you have access to SharePoint you can try an entirely different approach which is to do it all via a web application. The sharepoint plugins will allow hosting views on the documents directly in the browser. Note that this pretty much requires Internet Explorer to be fully usable though.

ShuggyCoUk
While being feasible, these options all require a third party applciation to open a seperate window. The requirement is to display it with other elements on the application.
RichieACC
The SharePoint one doesn't, but means wider changes to your application.I'm afraid the answer ,barring hackish hosting of externals processes as bounded controls, is likely to be - stop trying to show the document directly and show a limited subset of it.
ShuggyCoUk
The alternate is becoming a fully fledge OLE hosting app that embeds the actual office apps, but that absolutely requires the office install, and doesn't make preventing editing easy. It's also hard to do.
ShuggyCoUk
+1  A: 

SpreadsheetGear for .NET has an Excel Compatible Windows Forms control which will display your Excel workbooks (it will do lot more than that if you want it to). You can see what people say and download the free trial if you want to give it a try.

SpreasheetGear can also create images from charts and ranges of cells if you need to generate images to display in a web page.

Joe Erickson
As awesome as that looks, neither us, nor our client are prepared to pay that much for the component. Thanks for the suggestion though.
RichieACC
unfortunately there are not going to be any cheap ways of doing what you want without some expectation adjustment :)
spoon16
+3  A: 

Possibly interesting as well:

Save the documents to XPS using Microsoft Office 2007 (or print them to an XPS printer).

You can display the read-only XPS document either using the XPS viewer component or render page by page into a PNG or JPEG image. This rendering can be achieved quite easily using .NET 3.5 / WPF.

XpsDocument xpsDoc = new XpsDocument(xpsFileName, System.IO.FileAccess.Read);

FixedDocumentSequence docSeq = xpsDoc.GetFixedDocumentSequence();
const double scaleFactor = 0.8;
for (int pageNum = 0; pageNum < docSeq.DocumentPaginator.PageCount; pageNum++)
{
    DocumentPage docPage = docSeq.DocumentPaginator.GetPage(pageNum);

    // FIX: calling GetPage without calling UpdateLayout causes a memory leak
    ((FixedPage)docPage.Visual).UpdateLayout();

    RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)Math.Round(scaleFactor * docPage.Size.Width),
                (int)Math.Round(scaleFactor * docPage.Size.Height), (int)Math.Round(scaleFactor * 96), (int)Math.Round(scaleFactor * 96), PixelFormats.Default);
    renderTarget.Render(docPage.Visual);

    JpegBitmapEncoder encoder = new JpegBitmapEncoder();
    encoder.QualityLevel = 75;
    // Choose type here ie: JpegBitmapEncoder, etc
    //BitmapEncoder encoder = new PngBitmapEncoder();  // Choose type here ie: JpegBitmapEncoder, etc
    encoder.Frames.Add(BitmapFrame.Create(renderTarget));

    string pageImageFileName = string.Format("{0}-{1}.jpg", Path.Combine(Path.GetDirectoryName(xpsFileName), Path.GetFileNameWithoutExtension(xpsFileName)), pageNum);
            using (FileStream pageOutStream = new FileStream(pageImageFileName, FileMode.Create, FileAccess.Write))
    {
        encoder.Save(pageOutStream);
    }
}

This code needs references to the PresentationCore, PresentationFramework and ReachFramework assemblies.

EDIT: The code above contained a memory leak (see http://stackoverflow.com/questions/218681/opening-xps-document-in-net-causes-a-memory-leak). The workaround has been been inserted in the example.

0xA3
A: 

Disclaimer, I'm from Atalasoft

If you want to display PDF in any kind of .NET GUI (Winforms, ASP.NET, Silverlight, WPF), our DotImage with PDF Reader add-on supports it. It doesn't use Adobe and doesn't require anything to be installed on the client-machine or server (just our assemblies).

Lou Franco