如何打开Excel文件并在WPF中查看
本文关键字:WPF 何打开 Excel 文件 | 更新日期: 2023-09-27 18:08:10
我用我的c#应用程序创建了一些excel文件,并保存在我的电脑上。我想在我的应用程序中打开并查看它们,我该怎么做?我的应用程序是使用WPF c#开发的
可以利用预览处理程序机制。下面是我用来承载预览处理程序的控件:
public class FilePreviewControl : HwndHost {
private const int
Child = 0x40000000,
Visible = 0x10000000,
HostId = 0x00000002,
ClipChild = 0x02000000;
public static readonly DependencyProperty PathProperty = DependencyProperty.Register(
"Path", typeof (string), typeof (FilePreviewControl), new UIPropertyMetadata(Update));
public static readonly DependencyProperty ExtensionProperty = DependencyProperty.Register(
"Extension", typeof (string), typeof (FilePreviewControl), new UIPropertyMetadata(Update));
public static readonly DependencyProperty SourceStreamProperty = DependencyProperty.Register(
"SourceStream", typeof (Stream), typeof (FilePreviewControl), new UIPropertyMetadata(Update));
private readonly PreviewManager manager;
private IntPtr hwndHost;
public FilePreviewControl() {
this.manager = new PreviewManager();
}
public Stream SourceStream {
get { return (Stream) this.GetValue(SourceStreamProperty); }
set { this.SetValue(SourceStreamProperty, value); }
}
public string Extension {
get { return (string) this.GetValue(ExtensionProperty); }
set { this.SetValue(ExtensionProperty, value); }
}
public string Path {
get { return (string) this.GetValue(PathProperty); }
set { this.SetValue(PathProperty, value); }
}
private static void Update(DependencyObject d, DependencyPropertyChangedEventArgs e) {
((FilePreviewControl) d).RefreshPreview();
}
protected override HandleRef BuildWindowCore(HandleRef hwndParent) {
this.hwndHost = IntPtr.Zero;
this.hwndHost = CreateWindowEx(0, "static", "",
Child | Visible | ClipChild,
0, 0,
(int) this.ActualWidth, (int) this.ActualHeight,
hwndParent.Handle,
(IntPtr) HostId,
IntPtr.Zero,
0);
this.RefreshPreview();
return new HandleRef(this, this.hwndHost);
}
protected override void DestroyWindowCore(HandleRef hwnd) {
DestroyWindow(hwnd.Handle);
this.manager.Dispose();
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) {
base.OnRenderSizeChanged(sizeInfo);
var rect = new Rect(new Size(this.ActualWidth, this.ActualHeight));
this.manager.InvalidateAttachedPreview(rect);
}
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
handled = false;
return IntPtr.Zero;
}
[DllImport("user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Unicode)]
private static extern IntPtr CreateWindowEx(
int dwExStyle,
string lpszClassName,
string lpszWindowName,
int style,
int x,
int y,
int width,
int height,
IntPtr hwndParent,
IntPtr hMenu,
IntPtr hInst,
[MarshalAs(UnmanagedType.AsAny)] object pvParam);
[DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)]
private static extern bool DestroyWindow(IntPtr hwnd);
private void RefreshPreview() {
if (this.hwndHost == IntPtr.Zero)
return;
var filePath = this.Path;
var extension = this.Extension;
if (string.IsNullOrEmpty(extension) && !string.IsNullOrEmpty(filePath))
extension = System.IO.Path.GetExtension(filePath);
var shouldBeDeactivated =
this.Visibility != Visibility.Visible ||
(string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) && this.SourceStream == null ||
string.IsNullOrEmpty(extension);
if (shouldBeDeactivated) {
this.manager.Detach();
return;
}
var rect = new Rect(new Size(this.RenderSize.Width, this.RenderSize.Height));
try {
this.manager.AttachPreview(
this.hwndHost,
rect,
extension,
filePath,
this.SourceStream);
} catch (Exception exception) {
Trace.TraceError(exception.ToString());
}
}
public static bool CanPreview(string extension) {
return PreviewManager.GetPreviewHandlerKey(extension) != null;
}
#region Nested type: InteropStream
private sealed class InteropStream : IStream, IDisposable {
private readonly Stream stream;
private bool disposed;
public InteropStream(Stream sourceStream) {
if (sourceStream == null)
throw new ArgumentNullException("sourceStream");
this.stream = sourceStream;
}
#region IDisposable Members
public void Dispose() {
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region IStream Members
public void Clone(out IStream ppstm) {
throw new NotSupportedException();
}
public void Commit(int grfCommitFlags) {
throw new NotSupportedException();
}
public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) {
throw new NotSupportedException();
}
public void LockRegion(long libOffset, long cb, int dwLockType) {
throw new NotSupportedException();
}
[SecurityCritical]
public void Read(byte[] pv, int cb, IntPtr pcbRead) {
var count = this.stream.Read(pv, 0, cb);
if (pcbRead != IntPtr.Zero)
Marshal.WriteInt32(pcbRead, count);
}
public void Revert() {
throw new NotSupportedException();
}
[SecurityCritical]
public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) {
var origin = (SeekOrigin) dwOrigin;
var pos = this.stream.Seek(dlibMove, origin);
if (plibNewPosition != IntPtr.Zero)
Marshal.WriteInt64(plibNewPosition, pos);
}
public void SetSize(long libNewSize) {
this.stream.SetLength(libNewSize);
}
public void Stat(out STATSTG pstatstg, int grfStatFlag) {
pstatstg = new STATSTG {
type = 2,
cbSize = this.stream.Length,
grfMode = 0
};
if (this.stream.CanRead && this.stream.CanWrite)
pstatstg.grfMode |= 2;
else if (this.stream.CanWrite && !this.stream.CanRead)
pstatstg.grfMode |= 1;
else
throw new IOException();
}
public void UnlockRegion(long libOffset, long cb, int dwLockType) {
throw new NotSupportedException();
}
[SecurityCritical]
public void Write(byte[] pv, int cb, IntPtr pcbWritten) {
this.stream.Write(pv, 0, cb);
if (pcbWritten != IntPtr.Zero)
Marshal.WriteInt32(pcbWritten, cb);
}
#endregion
private void Dispose(bool disposing) {
if (this.disposed)
return;
if (disposing && this.stream != null)
this.stream.Dispose();
this.disposed = true;
}
~InteropStream() {
this.Dispose(false);
}
}
#endregion
private sealed class TempFile : IDisposable {
private string path;
public TempFile() : this(System.IO.Path.GetTempFileName()) {
}
private TempFile(string path) {
if (string.IsNullOrEmpty(path))
throw new ArgumentNullException("path");
this.path = path;
}
public string Path {
get {
if (this.path == null)
throw new ObjectDisposedException(this.GetType().Name);
return this.path;
}
}
#region IDisposable Members
public void Dispose() {
this.Dispose(true);
}
#endregion
private void Dispose(bool disposing) {
if (disposing)
GC.SuppressFinalize(this);
if (this.path == null)
return;
try {
File.Delete(this.path);
} catch {
Trace.TraceWarning("Can't delete file " + this.path);
} // best effort
this.path = null;
}
~TempFile() {
this.Dispose(false);
}
}
#region Nested type: PreviewManager
private sealed class PreviewManager : IDisposable {
private IPreviewHandler currentHandler;
private bool disposed;
private InteropStream stream;
#region IDisposable Members
public void Dispose() {
this.DisposeInternal();
GC.SuppressFinalize(this);
}
#endregion
public void AttachPreview(IntPtr handler, Rect viewRect, string extension, string filePath,
Stream sourceStream) {
this.Unload();
var classKey = GetPreviewHandlerKey(extension);
if (classKey == null)
return;
var guid = new Guid(classKey.GetValue(string.Empty).ToString());
var type = Type.GetTypeFromCLSID(guid, true);
var instance = Activator.CreateInstance(type);
var fileInit = instance as IInitializeWithFile;
var streamInit = instance as IInitializeWithStream;
if (streamInit != null && sourceStream != null) {
this.stream = new InteropStream(sourceStream);
streamInit.Initialize(this.stream, 0);
} else if (fileInit != null)
if (filePath != null)
fileInit.Initialize(filePath, 0);
else if (sourceStream != null)
using (var tempFile = new TempFile()) {
using (var fileStream = File.Create(tempFile.Path))
sourceStream.CopyTo(fileStream);
fileInit.Initialize(tempFile.Path, 0);
}
else
return;
else
return;
this.currentHandler = instance as IPreviewHandler;
if (this.currentHandler == null) {
this.Unload();
return;
}
var rect = new ShellRect(viewRect);
this.currentHandler.SetWindow(handler, ref rect);
this.currentHandler.SetRect(ref rect);
try {
this.currentHandler.DoPreview();
} catch {
this.Unload();
throw;
}
}
internal static RegistryKey GetPreviewHandlerKey(string extension) {
var commonGuid = new Guid("8895b1c6-b41f-4c1c-a562-0d564250836f");
var classKey =
Registry.ClassesRoot.OpenSubKey(string.Format(@"{0}'ShellEx'{1:B}", extension, commonGuid));
return classKey;
}
public void Detach() {
this.Unload();
}
public void InvalidateAttachedPreview(Rect viewRect) {
if (this.currentHandler == null)
return;
var rect = new ShellRect(viewRect);
this.currentHandler.SetRect(ref rect);
}
private void DisposeInternal() {
if (this.disposed)
return;
this.Unload();
this.disposed = true;
}
private void Unload() {
if (this.currentHandler != null) {
this.currentHandler.Unload();
Marshal.FinalReleaseComObject(this.currentHandler);
this.currentHandler = null;
}
if (this.stream != null) {
this.stream.Dispose();
this.stream = null;
}
}
~PreviewManager() {
this.DisposeInternal();
}
#region Nested type: IInitializeWithFile
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b7d14566-0509-4cce-a71f-0a554233bd9b")]
internal interface IInitializeWithFile {
void Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode);
}
#endregion
#region Nested type: IInitializeWithStream
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b824b49d-22ac-4161-ac8a-9916e8fa3f7f")]
internal interface IInitializeWithStream {
void Initialize(IStream pstream, uint grfMode);
}
#endregion
#region Nested type: IPreviewHandler
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("8895b1c6-b41f-4c1c-a562-0d564250836f")]
internal interface IPreviewHandler {
void SetWindow(IntPtr hwnd, ref ShellRect rect);
void SetRect(ref ShellRect rect);
void DoPreview();
void Unload();
void SetFocus();
void QueryFocus(out IntPtr phwnd);
[PreserveSig]
uint TranslateAccelerator(ref MSG pmsg);
}
#endregion
#region Nested type: ShellRect
[StructLayout(LayoutKind.Sequential)]
internal struct ShellRect {
public readonly int left;
public readonly int top;
public readonly int right;
public readonly int bottom;
public ShellRect(Rect rect) {
this.top = (int) rect.Top;
this.bottom = (int) rect.Bottom;
this.left = (int) rect.Left;
this.right = (int) rect.Right;
}
}
#endregion
}
#endregion
}
下面是它的用法:
<local:FilePreviewControl Path="Book1.xlsx" />
只有在你的电脑上安装了Microsoft Office才能正常工作
可以使用DocumentViewer
WPF控件
首先,您应该将office document
格式转换为XPS
格式。请看这篇文章。
然后将其绑定到DocumentViewer
控件的Document
属性。
XAML
<DocumentViewer Name="myDocumentViewer" Margin="0,0,0,59">
</DocumentViewer>
代码后面
myDocumentViewer.Document = this.ConvertPptxDocToXPSDoc(this.FileName, this.newXPSDocumentName).GetFixedDocumentSequence();
上海证券交易所的解决方案是低估。它工作得很好,优点是:
- 没有activeX msgBox(打开,保存,取消)像在WebBrowser解决方案
- 不需要regsvr32 dsofframer。使用AxFramerControl解决方案 在客户端机器中使用ocx作为管理员
- 不需要转换成XPS格式,所以你可以保持Excel格式
缺点是:
- 需要办公室
- 必须找到一种方法来终止Excel进程时,应用程序在Windows 7上关闭(不需要在Windows 10上,Excel终止自己)
- 文件是只读的
你只需要加上:
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security;
using System.Security.AccessControl;
并添加最新的Microsoft.Office.Interop.Excel参考
我只是想添加一个评论,但我没有足够的声誉。但是,这个解决方案可以节省您的时间!