在线预览Office(可另存图片)

来源:互联网 发布:sqlserver读写分离 编辑:程序博客网 时间:2024/06/05 19:56

支持的文件类型包括pdf,xls,xlsx,ppt,pptx,docx,doc,

Cache.cs:

using System;using System.Runtime.Caching;using Newtonsoft.Json.Linq;namespace Online.Core{    /// <summary>    ///     缓存框架    /// </summary>    public class CacheData    {        private const string CacheName = "System";        private static readonly MemoryCache MemoryCache = new MemoryCache(CacheName);        /// <summary>        ///     缓存过期时间        /// </summary>        private static DateTimeOffset DestroyTime        {            get { return DateTimeOffset.Now.AddMinutes(5); }        }        /// <summary>        ///     设置缓存        /// </summary>        /// <param name="name">要插入的缓存项的唯一标识符</param>        /// <param name="value">该缓存项的数据</param>        public static void Set(string name, JObject value)        {            if (MemoryCache.Contains(name))            {                MemoryCache[name] = value;            }            else            {                MemoryCache.Set(name, value, DestroyTime);            }        }        /// <summary>        ///     从缓存中返回一个项        /// </summary>        /// <param name="name">要获取的缓存项的唯一标识符</param>        /// <returns></returns>        public static JObject Get(string name)        {            return MemoryCache.Contains(name) ? JObject.Parse(MemoryCache.Get(name).ToString()) : null;        }        /// <summary>        ///     从缓存中移除某个缓存项        /// </summary>        /// <param name="name">要移除的缓存项的唯一标识符</param>        public static void Remove(string name)        {            MemoryCache.Remove(name);        }        /// <summary>        ///     确定缓存中是否包括指定的键值        /// </summary>        /// <param name="name">要搜索的缓存项的唯一标识符</param>        /// <returns></returns>        public static bool ContainsKey(string name)        {            return MemoryCache.Contains(name);        }    }}

Conversion.cs代码:

using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Imaging;using System.IO;using System.Runtime.InteropServices;using System.Threading.Tasks;using Aspose.Cells;using Aspose.Pdf.Devices;using Aspose.Slides;using Document = Aspose.Pdf.Document;using SaveFormat = Aspose.Words.SaveFormat;namespace Online.Core{    public interface IConversion    {        /// <summary>        ///     回调方法        /// </summary>        Action<int, string> CallBack { get; set; }        /// <summary>        ///     Office转换成图片        /// </summary>        /// <param name="filePath">文件路径</param>        /// <param name="resolution">图片质量</param>        void ConvertToImage(string filePath, int resolution);    }    /// <summary>    ///     Office转换工具    /// </summary>    public class Conversion    {        /// <summary>        ///     图片转换质量        /// </summary>        private const int Resolution = 170;        /// <summary>        ///     实例化转换工具        /// </summary>        /// <param name="filePath">文件路径</param>        /// <param name="fileExtension">文件扩展名</param>        /// <param name="callBack">回调方法</param>        public Conversion(string filePath, string fileExtension, Action<int, string> callBack)        {            switch (fileExtension.ToLower())            {                case ".doc":                case ".docx":                    ConversionFunc = new WordConversion();                    break;                case ".pdf":                    ConversionFunc = new PdfConversion();                    break;                case ".xls":                case ".xlsx":                    ConversionFunc = new ExcelConversion();                    break;                case ".ppt":                case ".pptx":                    ConversionFunc = new PptConversion();                    break;                default:                    throw new Exception("不支持的文件类型。");            }            FilePath = filePath;            ConversionFunc.CallBack = callBack;        }        private IConversion ConversionFunc { get; set; }        /// <summary>        ///     文件路径        /// </summary>        private string FilePath { get; set; }        /// <summary>        ///     Office转换成图片        /// </summary>        public void ConvertToImage()        {            ConversionFunc.ConvertToImage(FilePath, Resolution);            ConversionFunc.CallBack(0, "");        }    }    internal class PdfConversion : IConversion    {        private readonly List<Task> TaskList = new List<Task>();        public Action<int, string> CallBack { get; set; }        public void ConvertToImage(string filePath, int resolution)        {            var doc = new Document(filePath);            string imageName = Path.GetFileNameWithoutExtension(filePath);            for (int i = 1; i <= doc.Pages.Count; i++)            {                int pageNum = i;                string imgPath = string.Format("{0}_{1}.Jpeg", Path.Combine(Path.GetDirectoryName(filePath), imageName),                    i.ToString("000"));                if (File.Exists(imgPath))                {                    InvokeCallBack(pageNum, imgPath);                    continue;                }                using (var stream = new MemoryStream())                {                    var reso = new Resolution(resolution);                    var jpegDevice = new JpegDevice(reso, 100);                    jpegDevice.Process(doc.Pages[i], stream);                    using (Image image = Image.FromStream(stream))                    {                        new Bitmap(image).Save(imgPath, ImageFormat.Jpeg);                    }                }                InvokeCallBack(pageNum, imgPath);            }            Task.WaitAll(TaskList.ToArray());        }        private void InvokeCallBack(int pageNum, string imagePath)        {            var task = new Task(() => { CallBack.Invoke(pageNum, imagePath); });            TaskList.Add(task);            task.Start();        }    }    internal class WordConversion : IConversion    {        private readonly List<Task> TaskList = new List<Task>();        public Action<int, string> CallBack { get; set; }        public void ConvertToImage(string filePath, int resolution)        {            //先将Word转换为PDF文件            string pdfPath;            try            {                using (var convert = new WordToPdf())                {                    pdfPath = convert.ToPdf(filePath);                }            }            catch (COMException)            {                pdfPath = Path.ChangeExtension(filePath, "pdf");                if (!File.Exists(pdfPath))                {                    var doc = new Aspose.Words.Document(filePath);                    doc.Save(pdfPath, SaveFormat.Pdf);                }            }            //再将PDF转换为图片            var converter = new PdfConversion {CallBack = CallBack};            converter.ConvertToImage(pdfPath, resolution);        }        private void InvokeCallBack(int pageNum, string imagePath)        {            var task = new Task(() => { CallBack.Invoke(pageNum, imagePath); });            TaskList.Add(task);            task.Start();        }    }    internal class ExcelConversion : IConversion    {        public Action<int, string> CallBack { get; set; }        public void ConvertToImage(string filePath, int resolution)        {            var doc = new Workbook(filePath);            //先将Excel转换为PDF临时文件            string pdfPath = Path.ChangeExtension(filePath, "pdf");            doc.Save(pdfPath, Aspose.Cells.SaveFormat.Pdf);            //再将PDF转换为图片            var converter = new PdfConversion {CallBack = CallBack};            converter.ConvertToImage(filePath, resolution);        }    }    internal class PptConversion : IConversion    {        public Action<int, string> CallBack { get; set; }        public void ConvertToImage(string filePath, int resolution)        {            var doc = new Presentation(filePath);            //先将ppt转换为PDF文件            string tmpPdfPath = Path.ChangeExtension(filePath, "pdf");            doc.Save(tmpPdfPath, Aspose.Slides.Export.SaveFormat.Pdf);            //再将PDF转换为图片            var converter = new PdfConversion {CallBack = CallBack};            converter.ConvertToImage(filePath, resolution);        }    }}

FileManagement.cs代码:

using System;using System.Configuration;using System.IO;using System.Threading;using System.Threading.Tasks;namespace Online.Core{    /// <summary>    ///     文件管理    /// </summary>    public class FileManagement    {        private static readonly FileManagement Instance = new FileManagement();        private FileManagement()        {            var task = new Task(() =>            {                if (bool.Parse(AutoClear))                {                    Clear();                }                Thread.Sleep(24*60*60*1000);            });            task.Start();        }        /// <summary>        ///     文件清理时间        /// </summary>        public static string FileClearDay        {            get { return ConfigurationManager.AppSettings["FileClearDay"] ?? 10.ToString(); }            set            {                int day;                if (int.TryParse(value, out day))                {                    ConfigurationManager.AppSettings["FileClearDay"] = value;                }            }        }        /// <summary>        ///     是否自动清理        /// </summary>        public static string AutoClear        {            get { return ConfigurationManager.AppSettings["AutoClear"] ?? false.ToString(); }            set            {                bool auto;                if (bool.TryParse(value, out auto))                {                    ConfigurationManager.AppSettings["AutoClear"] = value;                }            }        }        private static DirectoryInfo FileDirectory        {            get { return new DirectoryInfo(string.Format(@"{0}\FileInfo\", AppDomain.CurrentDomain.BaseDirectory)); }        }        /// <summary>        ///     清理过期缓存        /// </summary>        public static void Clear()        {            foreach (FileInfo file in FileDirectory.GetFiles("*", SearchOption.AllDirectories))            {                if ((DateTime.Now - file.CreationTime).TotalDays > double.Parse(FileClearDay))                {                    file.Delete();                }            }        }        /// <summary>        ///     清理全部缓存        /// </summary>        public static void ClearAll()        {            FileDirectory.Delete(true);        }    }}

Network.cs

using System;using System.IO;using System.Net;namespace Online.Core{    /// <summary>    ///     从URL获取文件    /// </summary>    public class Network    {        public Network(string url)        {            FilePath = GetFileInfo(new Uri(url));        }        /// <summary>        ///     文件本地路径        /// </summary>        public string FilePath { get; set; }        /// <summary>        ///     文件扩展名        /// </summary>        public string FileExtension        {            get { return FilePath.Substring(FilePath.LastIndexOf(".")); }        }        private static string GetFileInfo(Uri uri)        {            var request = (HttpWebRequest) WebRequest.Create(uri);            request.ContentType = "application/x-www-form-urlencoded";            string filePath = GetFilePath(uri);            if (!File.Exists(filePath))            {                using (WebResponse response = request.GetResponse())                {                    var length = (int) response.ContentLength;                    using (var reader = new BinaryReader(response.GetResponseStream()))                    {                        using (FileStream stream = File.Create(filePath))                        {                            stream.Write(reader.ReadBytes(length), 0, length);                        }                    }                }            }            return filePath;        }        /// <summary>        ///     获取文件本地路径        /// </summary>        /// <param name="uri">网络请求地址</param>        private static string GetFilePath(Uri uri)        {            string localPath = uri.LocalPath;            string filePath = localPath.Substring(localPath.LastIndexOf("/") + 1);            string folderPath = string.Format(@"{0}\FileInfo\{1}\{2}\", AppDomain.CurrentDomain.BaseDirectory, uri.Host,                localPath.Remove(localPath.LastIndexOf("/")).Replace("/", @"\"));            if (!Directory.Exists(folderPath))            {                Directory.CreateDirectory(folderPath);            }            return folderPath + filePath;        }    }}

WordToPdf.cs代码:

using System;using System.IO;using System.Runtime.InteropServices;using Word;namespace Online.Core{    /// <summary>    ///     通过COM组件进行格式转换    /// </summary>    internal class WordToPdf : IDisposable    {        private readonly dynamic office;        public WordToPdf()        {            foreach (                Type type in                    new[]                    {                        Type.GetTypeFromProgID("Word.Application"), Type.GetTypeFromProgID("KWps.Application"),                        Type.GetTypeFromProgID("wps.Application")                    })            {                if (type != null)                {                    try                    {                        office = Activator.CreateInstance(type);                        return;                    }                    catch (COMException)                    {                    }                }            }            throw new COMException("未找到可用的COM组件。");        }        public void Dispose()        {            if (office != null)            {                office.Quit();            }        }        public string ToPdf(string wpsFilename, string pdfFilename = null)        {            if (wpsFilename == null)            {                throw new COMException("未找到指定文件。");            }            if (pdfFilename == null)            {                pdfFilename = Path.ChangeExtension(wpsFilename, "pdf");            }            if (!File.Exists(pdfFilename))            {                dynamic doc = office.Documents.Open(wpsFilename, Visible: false);                doc.ExportAsFixedFormat(pdfFilename, WdExportFormat.wdExportFormatPDF);                doc.Close();            }            return pdfFilename;        }    }}

Office.aspx

<!DOCTYPE html><html>    <head runat="server">        <title>Office在线预览</title>        <link type="text/css" rel="stylesheet" href="/Resources/Style/Office.css" />    </head>    <body>        <div ng-app="app" ng-controller="controller">            <div ng-cloak class="Loading ng-cloak" ng-show="imageList == null || imageList.length == 0">                <img alt="" src="/Resources/Images/Loading.gif" />            </div>            <div ng-cloak class="Error ng-cloak" ng-show="status == 'error'">                <h1>:(</h1>                <p class="Explain">真抱歉,页面发生了错误。</p>                <p class="Hint"><span>错误原因:</span><span ng-bind="message"></span></p>            </div>            <div ng-cloak class="ImageList ng-cloak" ng-show="status == 'running' || status == 'finish'">                <div class="Image" ng-repeat="item in imageList | orderBy : 'pageNum'">                    <img ng-src="{{item.imageUrl}}" />                </div>            </div>            <div ng-cloak class="Loading_Bottom ng-cloak" ng-show="status == 'running' && imageList != null && imageList.length != 0">                <img alt="" src="/Resources/Images/Loading.gif" />            </div>        </div>        <script type='text/javascript' src='/Resources/Scripts/jquery-1.8.0.min.js'></script>        <script type='text/javascript' src='/Resources/Scripts/angular.min.js'></script>        <script type="text/javascript">            angular.module('app', []).controller('controller', function($scope, $http) {                $scope.status = "loading";                $scope.GetImage = function() {                    $http({                        method: 'POST',                        url: 'Office.aspx',                        data: "Mode=GetResult&PageId=<%= SessionId %>",                        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },                    }).success(function(data) {                        $scope.status = data.status;                        if (data.status == "running") {                            $scope.imageList = data.imageList;                            setTimeout(function() {                                $scope.GetImage();                            }, 100);                        } else if (data.status == "finish") {                            $scope.imageList = data.imageList;                        } else {                            $scope.message = data.message;                        }                    });                };                $scope.GetImage();            });        </script>    </body></html>

Office.aspx.cs

using System;using System.Threading.Tasks;using System.Web.UI;using Newtonsoft.Json.Linq;using Online.Core;namespace Web{    public partial class Office : Page    {        /// <summary>        ///     页面ID        /// </summary>        public string SessionId { get; set; }        protected void Page_Load(object sender, EventArgs e)        {            switch (Request["Mode"])            {                case "GetResult":                    GetResult(Request["PageId"]);                    return;                default:                    SessionId = Session.SessionID + Request["FileUrl"];                    GetFile(Request["FileUrl"]);                    return;            }        }        /// <summary>        ///     开始加载Office文件        /// </summary>        /// <param name="fileUrl">文件Url</param>        private void GetFile(string fileUrl)        {            //避免页面加载完成前重复刷新造成的重复获取            if (!CacheData.ContainsKey(SessionId))            {                CacheData.Set(SessionId,                    new JObject {{"status", "running"}, {"message", ""}, {"imageList", new JArray()}});                new Task(() =>                {                    if (!string.IsNullOrEmpty(fileUrl))                    {                        try                        {                            var network = new Network(fileUrl);                            new Conversion(network.FilePath, network.FileExtension, CallBack).ConvertToImage();                        }                        catch (Exception ex)                        {                            AlertError(ex.Message);                        }                    }                    else                    {                        AlertError("请输入文件地址");                    }                }).Start();            }        }        /// <summary>        ///     返回处理结果        /// </summary>        /// <param name="pageId">页面唯一ID</param>        private void GetResult(string pageId)        {            Response.Clear();            Response.ContentType = "application/json";            Response.Write(CacheData.Get(pageId));            string status = CacheData.Get(pageId)["status"].ToString();            if (status == "finish" || status == "error")            {                CacheData.Remove(pageId);            }            Response.End();        }        /// <summary>        ///     获取图片地址        /// </summary>        /// <param name="pageNum">当前图片次序</param>        /// <param name="imageUrl">图片Url</param>        public void CallBack(int pageNum, string imageUrl)        {            lock (this)            {                JObject jObject = CacheData.Get(SessionId);                if (jObject["status"].ToString() == "running")                {                    if (pageNum == 0)                    {                        jObject["status"] = "finish";                    }                    else                    {                        ((JArray) jObject["imageList"]).Add(new JObject                        {                            {"pageNum", pageNum},                            {"imageUrl", FromLocal(imageUrl)}                        });                    }                    CacheData.Set(SessionId, jObject);                }            }        }        /// <summary>        ///     页码报错提示        /// </summary>        /// <param name="message">提示信息</param>        private void AlertError(string message)        {            CacheData.Set(SessionId,                new JObject {{"status", "error"}, {"message", message}, {"imageList", new JArray()}});        }        /// <summary>        ///     本地路径转Url        /// </summary>        private string FromLocal(string filePath)        {            string fileUrl = filePath.Replace(AppDomain.CurrentDomain.BaseDirectory, ""); //转换成相对路径            fileUrl = "/" + fileUrl.Replace(@"\", @"/");            return fileUrl;        }    }}

Setting.aspx内容:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Setting.aspx.cs" Inherits="Web.Setting" %><%@ Import Namespace="Online.Core" %><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    <title>Office在线设置页面</title>    <link type="text/css" rel="stylesheet" href="/Resources/Style/bootstrap/css/bootstrap.min.css" />    <link type="text/css" rel="stylesheet" href="/Resources/Style/bootstrap/css/docs.min.css" />    <link type="text/css" rel="stylesheet" href="/Resources/Style/Setting.css" /></head><body>    <div ng-app="app" ng-controller="controller">        <div class="panel panel-info">            <div class="panel-heading">                <h3 class="panel-title">参数设置</h3>            </div>            <div ng-cloak class="panel-body ng-cloak">                <div class="input-group">                    <span class="input-group-addon">设置文件过期时间(天)</span>                    <input type="text" class="form-control" ng-model="clearDay">                </div>            </div>            <div ng-cloak class="panel-body ng-cloak">                <div class="btn-group btn-group-justified">                    <div class="btn-group" role="group">                        <button type="button" class="btn btn-default" ng-click="Query('Function', 'Clear', '', '清理成功')">清理过期缓存文件</button>                    </div>                    <div class="btn-group" role="group">                        <button type="button" class="btn btn-default btn-center" ng-click="Query('Function', 'ClearAll', '', '清理成功')">清理所有缓存文件</button>                    </div>                    <div class="btn-group" role="group">                        <button type="button" class="btn btn-default" ng-class="{true:'active'}[auto]" ng-click="AutoClear()">自动清理过期文件</button>                    </div>                </div>            </div>        </div>        <div class="panel panel-info">            <div class="panel-heading">                <h3 class="panel-title">COM检测</h3>            </div>            <div ng-cloak class="panel-body ng-cloak">                <p>COM组件可以使OFFICE在页面总呈现更好的效果。</p>                <div class="bs-callout bs-callout-info" ng-repeat="item in environment">                    <h4 style="margin-bottom: 25px;" ng-bind="item.Name"></h4>                    <div class="alert" ng-repeat="node in item.Data" ng-class="{true:'alert-success',false:'alert-danger'}[node.Status]">                        <span ng-bind="node.Name"></span>                        <span ng-if="node.Status">检测成功</span>                        <span ng-if="!node.Status">检测失败</span>                        <p style="font-size: 11px; margin: 10px 0;" ng-if="!node.Status" ng-bind="node.Message"></p>                    </div>                </div>            </div>        </div>    </div>    <script type='text/javascript' src='/Resources/Scripts/jquery-1.8.0.min.js'></script>    <script type='text/javascript' src='/Resources/Scripts/angular.min.js'></script>    <script type="text/javascript">        angular.module('app', []).controller('controller', function($scope, $http) {            $scope.auto = <%= FileManagement.AutoClear %>;                $scope.clearDay = <%= FileManagement.FileClearDay %>;                $scope.environment = <%= EnvironmentCheck %>;                $scope.Query = function(action, name, value, message) {                    $http.get("/Setting.aspx?Action=" + action + "&name=" + name + "&value=" + value).success(function() {                        alert(message || '设置成功');                    }).error(function(data) {                        alert(data);                    });                };                $scope.AutoClear = function() {                    $scope.auto = !$scope.auto;                    $scope.Query('Property', 'AutoClear', $scope.auto);                };            });    </script></body></html>

Setting.aspx.cs代码:

using System;using System.Collections.Generic;using System.Reflection;using System.Runtime.InteropServices;using System.Web.UI;using Newtonsoft.Json.Linq;using Online.Core;namespace Web{    public partial class Setting : Page    {        /// <summary>        ///     COM环境检测        /// </summary>        public JArray EnvironmentCheck        {            get            {                var checks = new Dictionary<string, CheckModel[]>();                checks.Add("Word: 检测COM组件是否存在", new[]                {                    new CheckModel                    {                        Name = "WPS",                        Status =                            Type.GetTypeFromProgID("KWps.Application") != null ||                            Type.GetTypeFromProgID("wps.Application") != null                    },                    new CheckModel {Name = "OFFICE", Status = Type.GetTypeFromProgID("Word.Application") != null}                });                checks.Add("Word: 检测COM组件是否可用", new Func<CheckModel[]>(() =>                {                    CheckModel[] checkModels = { new CheckModel { Name = "WPS" }, new CheckModel { Name = "OFFICE" } };                    Type[] typeArray =                    {                        Type.GetTypeFromProgID("KWps.Application") ?? Type.GetTypeFromProgID("wps.Application"),                        Type.GetTypeFromProgID("Word.Application")                    };                    for (int i = 0; i < typeArray.Length; i++)                    {                        try                        {                            if (typeArray[i] != null)                            {                                Activator.CreateInstance(typeArray[i]);                                checkModels[i].Status = true;                            }                        }                        catch (COMException e)                        {                            checkModels[i].Message = e.Message;                        }                    }                    return checkModels;                }).Invoke());                var resultArray = new JArray();                foreach (string check in checks.Keys)                {                    var result = new JObject();                    result.Add("Name", check);                    result.Add("Data", new JArray());                    foreach (CheckModel checkModel in checks[check])                    {                        var item = new JObject();                        foreach (PropertyInfo property in checkModel.GetType().GetProperties())                        {                            object value = property.GetValue(checkModel, null);                            switch (property.PropertyType.Name)                            {                                case "Boolean":                                    item.Add(property.Name, bool.Parse(value.ToString()));                                    break;                                case "String":                                    item.Add(property.Name, value as string);                                    break;                            }                        }                        (result["Data"] as JArray).Add(item);                    }                    resultArray.Add(result);                }                return resultArray;            }        }        protected void Page_Load(object sender, EventArgs e)        {            try            {                switch (Request["Action"])                {                    case "Property":                        if (typeof(FileManagement).GetProperty(Request["Name"]) != null)                        {                            typeof(FileManagement).GetProperty(Request["Name"]).SetValue(null, Request["Value"], null);                        }                        return;                    case "Function":                        if (typeof(FileManagement).GetMethod(Request["Name"]) != null)                        {                            typeof(FileManagement).GetMethod(Request["Name"]).Invoke(null, null);                        }                        return;                    default:                        return;                }            }            catch (Exception ex)            {                Response.Clear();                Response.Write(ex.Message);                Response.End();            }        }        public class CheckModel        {            public string Name { get; set; }            public bool Status { get; set; }            public string Message { get; set; }        }    }}

注意:电脑需要安装office 2007或以上版本

运行结果如图:

这里写图片描述


这里写图片描述


这里写图片描述


这里写图片描述


这里写图片描述

原创粉丝点击