1. 程式人生 > >C# 資料備份和檔案備份

C# 資料備份和檔案備份

在系統使用一段時間可能由於某些原因需要將以前的資料和檔案備份到檔案
描述:將DB中的多個table 資料備份到Excel檔案並打包壓縮為zip,將需要備份的檔案打包壓縮Zip後刪除檔案

下面是使用DocumentFormat.OpenXml 和Microsoft.Practices的一個幫助類,Copy程式碼可以直接使用
需要引進如下圖dll
在這裡插入圖片描述

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks; 
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;

namespace databackupandfilebackup
{
    public class CommonFunctions
    {
        #region Data backup  
        /// <summary>
         /// 將dataset的資料集備份到EXCEL檔案 每個table為一個檔案,最後將所有匯出的excel檔案壓縮到zip檔案裡
         /// </summary>
         /// <param name="dataset">資料集</param>
         /// <param name="houseKeepingFilePath">檔案備份路徑</param>
        public static void HousekeepDataBackUp(DataSet dataset,string houseKeepingFilePath)
        {
            try
            {
                string HouseKeepingFilePath = houseKeepingFilePath;
                //Get data
                DataSet ds = dataset;

                int tablescount = ds.Tables.Count;
                //注意構造此Dataset時
                //此處Dataset中的最後一個table中儲存的是前面tables的表名稱
               // ds = SqlHelper.ExecuteDataSet("[SRC].[USP_Housekeeping_GetAllData]", null);
                
                string[] datanames = new string[ds.Tables.Count - 1];
                string[] dataFileNames = new string[ds.Tables.Count - 1];

                //迴圈獲得每個table檔案
                for (int i = 0; i < ds.Tables.Count - 1; i++)
                {
                    //建立檔案
                    string tablenamestr = HouseKeepingFilePath + "\\Housekeeping_" + ds.Tables[tablescount].Rows[0][i] + "_" + DateTime.Now.ToString("yyyyMMdd") + ".xlsx";
                    //檔案路徑陣列
                    datanames[i] = tablenamestr;
                    //檔名陣列
                    dataFileNames[i] = "Housekeeping_" + ds.Tables[tablescount].Rows[0][i] + "_" + DateTime.Now.ToString("yyyyMMdd") + ".xlsx";
                    //匯出到excel檔案
                    ExportExcel(ds.Tables[i], HouseKeepingFilePath + "\\", tablenamestr, "Sheet1");
                }
                //建立資料夾
                string dataHouseKeepingFilePath = HouseKeepingFilePath + "\\Housekeeping_Data" + DateTime.Now.ToString("yyyyMMdd");
                if (!Directory.Exists(dataHouseKeepingFilePath))//No find path
                {
                    Directory.CreateDirectory(dataHouseKeepingFilePath);//Create a folder for a path
                }
                //將檔案copy到資料夾
                for (int i = 0; i < datanames.Length; i++)
                {
                    if (File.Exists(datanames[i]))
                    {
                        File.Copy(datanames[i], dataHouseKeepingFilePath + "\\" + dataFileNames[i], true);
                        File.Delete(datanames[i]);
                    }
                }
                //建立zip檔案
                string HouseKeepingDatePathFilezip = HouseKeepingFilePath + "\\HouseKeeping_Data_" + DateTime.Now.ToString("yyyyMMdd") + ".zip";
                if (!File.Exists(HouseKeepingDatePathFilezip))
                {
                    FileStream ff = File.Create(HouseKeepingDatePathFilezip);
                    ff.Close();
                }
                //將資料夾打包到Zip檔案
                PackageFile.PackageFolder(dataHouseKeepingFilePath, HouseKeepingDatePathFilezip, true);

                //Delete the folders and files that have just been created
                if (Directory.Exists(dataHouseKeepingFilePath))
                {
                    Directory.Delete(dataHouseKeepingFilePath, true);
                }
            }
            catch (Exception ex)
            {
                throw;
            }

        }
        #endregion


        #region File backup and delete
        public static void FileBackUpAndDeleted(DataSet dataset, string filePath, string houseKeepingFilePath)
        {
            try
            {
                //原檔案儲存路徑
                string FilePath = filePath; 
                //備份檔案儲存路徑
                string HouseKeepingFilePath = houseKeepingFilePath ; 
                //備份並壓縮檔案儲存路徑    
                string HouseKeepingFilePathzip = HouseKeepingFilePath;
                //Dataset 是需要刪除的檔名稱,檔名是儲存在DB中 
                DataSet ds = dataset; 

                if (ds.Tables.Count > 0)
                {
                    if (ds.Tables[0].Rows.Count > 0)
                    {
                        //獲得壓縮檔案的絕對路徑
                        string HouseKeepingFilePathFilezip = HouseKeepingFilePath + "\\HouseKeeping_Attachment_" + DateTime.Now.ToString("yyyyMMdd") + ".zip";
                        if (!File.Exists(HouseKeepingFilePathFilezip))
                        {
                            FileStream ff = File.Create(HouseKeepingFilePathFilezip);
                            ff.Close();
                        }
                        //建立檔案
                        HouseKeepingFilePath = HouseKeepingFilePath + DateTime.Now.ToString("yyyyMMddHHmmss");
                        if (!Directory.Exists(HouseKeepingFilePath))//If the path does not exist
                        {
                            Directory.CreateDirectory(HouseKeepingFilePath);//Create a folder for a path
                        }
                        //獲得要備份的檔名的陣列
                        string[] filenames = new string[ds.Tables[0].Rows.Count];
                        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                        {
                            //FileName為DB中儲存檔名的欄位名稱
                            filenames[i] = FilePath + "\\" + ds.Tables[0].Rows[i]["FileName"].ToString();
                            if (File.Exists(filenames[i]))
                            {
                                File.Copy(filenames[i], HouseKeepingFilePath + "\\" + ds.Tables[0].Rows[i]["FileName"].ToString(), true);
                            }
                        }
                        //Packaging and compressing folders
                        PackageFile.PackageFolder(HouseKeepingFilePath, HouseKeepingFilePathFilezip, true);

                        //Delete the folders and files that have just been created
                        if (Directory.Exists(HouseKeepingFilePath))
                        {
                            Directory.Delete(HouseKeepingFilePath, true);
                        }
                        //File deletion
                        DeleteMulti(filenames);
                    }
                }
            }
            catch (Exception ex)
            {
              //add log
                throw;
            }
        }
        /// <summary>
        /// Delete multiple files
        /// </summary>
        /// <param name="sourceFileList"></param>
        public static void DeleteMulti(string[] sourceFileList)
        {
            try
            {
                foreach (var item in sourceFileList)
                {
                    if (File.Exists(item))
                    {
                        File.Delete(item);
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        #endregion
        
        
        #region 匯出方法
        public static bool ExportExcel(DataTable dt, string templateFile, string exportFile, string sheetName = "Sheet1", int startRowIndex = 2)
        {
            bool flag = true;
            try
            {
                CreateExcelExt(exportFile, sheetName);

                FileInfo fi = new FileInfo(exportFile);
                fi.Attributes = fi.Attributes & ~FileAttributes.ReadOnly & ~FileAttributes.Hidden;

                using (SpreadsheetDocument document = SpreadsheetDocument.Open(exportFile, true, new OpenSettings() { AutoSave = true }))
                {
                    IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName);

                    if (string.IsNullOrEmpty(sheets.First().Id))
                    {
                        throw new Exception("sheet is empty");
                    }

                    WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);

                    SheetData sd = worksheetPart.Worksheet.Descendants<SheetData>().FirstOrDefault();

                    Row headerRow = new Row();
                    foreach (DataColumn column in dt.Columns)
                    {
                        Cell cell = new Cell()
                        {
                            DataType = CellValues.String,
                            CellValue = new CellValue(column.ColumnName)
                        };
                        headerRow.Append(cell);
                    }
                    sd.Append(headerRow);

                    int rowIndex = startRowIndex;
                    foreach (DataRow dr in dt.Rows)
                    {
                        Row row = new Row();
                        row.RowIndex = (UInt32)rowIndex++;

                        int colIndex = 0;
                        foreach (DataColumn dc in dt.Columns)
                        {
                            Cell cell = new Cell();
                            CellValue cv = new CellValue(FormatValue(dr[dc].ToString(), dc, cell));
                            cell.Append(cv);
                            row.Append(cell);

                            colIndex++;
                        }

                        sd.Append(row);
                    }


                    //Save
                    worksheetPart.Worksheet.Save();
                    document.WorkbookPart.Workbook.Save();
                }

            }
            catch (Exception ex)
            {
                flag = false;
                throw ex;
            }
            return flag;
        }

        public static bool CreateExcelExt(string strPathName, string sheetname)
        {
            try
            {
                using (SpreadsheetDocument m_Doc = SpreadsheetDocument.Create(strPathName, SpreadsheetDocumentType.Workbook))
                {
                    // WorkbookPart
                    var m_WorkBookPart = m_Doc.AddWorkbookPart();
                    // Workbook
                    var m_WorkBook = m_WorkBookPart.Workbook = new Workbook();
                    // Sheets
                    var m_Sheets = m_WorkBook.AppendChild<Sheets>(new Sheets());
                    // ShareTable
                    m_WorkBookPart.AddNewPart<SharedStringTablePart>();

                    var m_ShareTable = m_WorkBookPart.SharedStringTablePart.SharedStringTable = new SharedStringTable();

                    if (false == sheetInsert(sheetname, m_Doc, m_Sheets, m_WorkBook))
                    {
                        return false;
                    }
                }

            }
            catch (Exception Ex)
            {
                Console.WriteLine(Ex.Message);
                return false;
            }


            return true;
        }

        public static bool sheetInsert(string sheetName, SpreadsheetDocument m_Doc, Sheets m_Sheets, Workbook m_WorkBook)
        {
            try
            {
                WorksheetPart newWorksheetPart = m_Doc.WorkbookPart.AddNewPart<WorksheetPart>();
                newWorksheetPart.Worksheet = new Worksheet(new SheetData());

                uint sheetID = 1;
                if (m_Sheets.Descendants<Sheet>().Count() > 0)
                {
                    sheetID = m_Sheets.Descendants<Sheet>().Select(S => S.SheetId.Value).Max() + 1;
                }

                Sheet newSheet = new Sheet()
                {
                    Name = sheetName,
                    SheetId = sheetID,
                    Id = m_Doc.WorkbookPart.GetIdOfPart(newWorksheetPart),
                };

                m_Sheets.Append(newSheet);
                var m_WorkSheetPart = newWorksheetPart;
                var m_WorkSheet = m_WorkSheetPart.Worksheet;

                m_WorkSheet.Save();
                m_WorkBook.Save();
            }
            catch (Exception Ex)
            {
                Console.WriteLine(Ex.Message);
                return false;
            }

            return true;
        }

        private static string FormatValue(string value, DataColumn col, Cell cell)
        {
            if (col.DataType.FullName == "System.Decimal" && (!string.IsNullOrEmpty(value)))
            {
                cell.DataType = CellValues.Number;
            }
            else if (col.DataType.FullName == "System.DateTime" && (!string.IsNullOrEmpty(value)))
            {
                cell.DataType = CellValues.String;
                value = Convert.ToDateTime(value, System.Globalization.CultureInfo.CurrentCulture).ToString(System.Globalization.CultureInfo.CurrentCulture);
            }
            else if (col.DataType.FullName == "System.Boolean")
            {
                cell.DataType = CellValues.String;
                value = string.IsNullOrEmpty(value) ? "" : Convert.ToBoolean(value, System.Globalization.CultureInfo.CurrentCulture) ? "True" : "False";
            }
            else
            {
                cell.DataType = CellValues.String;
            }
            return value;
        }

        #endregion

    }

    /// <summary>
    /// 1.Package folder
    /// 2.Compress file and Uncompress file
    /// 3.Extract Part file
    /// </summary>
    public static class PackageFile
    {
        /// <summary>
        /// Package a folder to a zip file
        /// </summary>
        /// <param name="folderName">The folder path</param>
        /// <param name="compressedFileName">The zip file name full path</param>
        /// <param name="overrideExisting">The override flag</param>
        /// <returns>Return true or false</returns>
        public static bool PackageFolder(string folderName, string compressedFileName, bool overrideExisting)
        {
            if (!string.IsNullOrEmpty(folderName) && folderName.EndsWith(@"\", StringComparison.OrdinalIgnoreCase))
                folderName = folderName.Remove(folderName.Length - 1);
            bool result = false;
            if (!Directory.Exists(folderName))
            {
                return result;
            }

            if (!overrideExisting && File.Exists(compressedFileName))
            {
                return result;
            }
            try
            {
                using (Package package = Package.Open(compressedFileName, FileMode.Create))
                {
                    var fileList = Directory.EnumerateFiles(folderName, "*", SearchOption.AllDirectories);
                    foreach (string fileName in fileList)
                    {

                        //The path in the package is all of the subfolders after folderName  
                        string pathInPackage;
                        pathInPackage = Path.GetDirectoryName(fileName).Replace(folderName, string.Empty) + "/" + Path.GetFileName(fileName);

                        Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(pathInPackage, UriKind.Relative));
                        PackagePart packagePartDocument = package.CreatePart(partUriDocument, "", CompressionOption.Maximum);
                        using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                        {
                            fileStream.CopyTo(packagePartDocument.GetStream());
                        }
                    }
                }
                result = true;
            }
            catch (Exception e)
            {
                //throw new Exception("Error zipping folder " + folderName, e);
                throw new IOException("Error zipping folder " + folderName, e);
            }

            return result;
        }

        /// <summary>  
        /// Compress a file into a ZIP archive as the container store  
        /// </summary>  
        /// <param name="fileName">The file to compress</param>  
        /// <param name="compressedFileName">The archive file</param>  
        /// <param name="overrideExisting">override existing file</param>  
        /// <returns>Return true or false</returns>  
        public static bool CompressFile(string fileName, string compressedFileName, bool overrideExisting)
        {
            bool result = false;

            if (!File.Exists(fileName))
            {
                return result;
            }

            if (!overrideExisting && File.Exists(compressedFileName))
            {
                return result;
            }

            try
            {
                Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(Path.GetFileName(fileName), UriKind.Relative));

                using (Package package = Package.Open(compressedFileName, FileMode.OpenOrCreate))
                {
                    if (package.PartExists(partUriDocument))
                    {
                        package.DeletePart(partUriDocument);
                    }

                    PackagePart packagePartDocument = package.CreatePart(partUriDocument, "", CompressionOption.Maximum);
                    using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                    {
                        fileStream.CopyTo(packagePartDocument.GetStream());
                    }
                }
                result = true;
            }
            catch (Exception e)
            {
                // throw new Exception("Error zipping file " + fileName, e);
                throw new IOException("Error zipping file " + fileName, e);

            }

            return result;
        }

        /// <summary>  
        /// Extract a container Zip. NOTE: container must be created as Open Packaging Conventions (OPC) specification  
        /// </summary>  
        /// <param name="folderName">The folder to extract the package to</param>  
        /// <param name="compressedFileName">The package file</param>  
        /// <param name="overrideExisting">override existing files</param>  
        /// <returns>Return true or false</returns>  
        public static bool UncompressFile(string folderName, string compressedFileName, bool overrideExisting)
        {
            bool result = false;
            try
            {
                if (!File.Exists(compressedFileName))
                {
                    return result;
                }

                DirectoryInfo directoryInfo = new DirectoryInfo(folderName);
                if (!directoryInfo.Exists)
                    directoryInfo.Create();

                using (Package package = Package.Open(compressedFileName, FileMode.Open, FileAccess.Read))
                {
                    foreach (PackagePart packagePart in package.GetParts())
                    {
                        ExtractPart(packagePart, folderName, overrideExisting);
                    }
                }

                result = true;
            }
            catch (Exception e)
            {
                //throw new Exception("Error unzipping file " + compressedFileName, e);
                throw new IOException("Error unzipping file " + compressedFileName, e);
            }

            return result;
        }

        /// <summary>
        /// Extract package part
        /// </summary>
        /// <param name="packagePart">The PackagePart object</param>
        /// <param name="targetDirectory">The target path</param>
        /// <param name="overrideExisting">override existing files</param>
        private static void ExtractPart(PackagePart packagePart, string targetDirectory, bool overrideExisting)
        {
            //string stringPart = targetDirectory + HttpUtility.UrlDecode(packagePart.Uri.ToString()).Replace('\\', '/');
            string stringPart = targetDirectory + packagePart.Uri.ToString().Replace('\\', '/');

            if (!Directory.Exists(Path.GetDirectoryName(stringPart)))
                Directory.CreateDirectory(Path.GetDirectoryName(stringPart));

            if (!overrideExisting && File.Exists(stringPart))
                return;
            using (FileStream fileStream = new FileStream(stringPart, FileMode.Create))
            {
                packagePart.GetStream().CopyTo(fileStream);
            }
        }

    }

}