/// <summary> /// Saves the <paramref name="data"/> byte array to the <paramref name="outputFile"/> /// </summary> /// <param name="data">The stream as byte array</param> /// <param name="outputFile">The output filename with path</param> /// <returns></returns> /// <exception cref="OfficeExtractor.Exceptions.OEFileIsCorrupt">Raised when the file is corrupt</exception> internal string SaveByteArrayToFile(byte[] data, string outputFile) { // Because the data is stored in a stream we have no name for it so we // have to check the magic bytes to see with what kind of file we are dealing Logger.WriteToLog($"Saving byte array with length '{data.Length}' to file '{outputFile}'"); var extension = Path.GetExtension(outputFile); if (string.IsNullOrEmpty(extension)) { var fileType = FileTypeSelector.GetFileTypeFileInfo(data); if (fileType != null && !string.IsNullOrEmpty(fileType.Extension)) { outputFile += "." + fileType.Extension; } if (fileType != null) { extension = "." + fileType.Extension; } } // Check if the output file already exists and if so make a new one outputFile = FileManager.FileExistsMakeNew(outputFile); if (extension != null) { switch (extension.ToUpperInvariant()) { case ".XLS": case ".XLT": case ".XLW": using (var memoryStream = new MemoryStream(data)) using (var compoundFile = new CompoundFile(memoryStream)) { Excel.SetWorkbookVisibility(compoundFile.RootStorage); compoundFile.Save(outputFile); } break; case ".XLSB": case ".XLSM": case ".XLSX": case ".XLTM": case ".XLTX": using (var memoryStream = new MemoryStream(data)) { var file = Excel.SetWorkbookVisibility(memoryStream); File.WriteAllBytes(outputFile, file.ToArray()); } break; default: File.WriteAllBytes(outputFile, data); break; } } else { File.WriteAllBytes(outputFile, data); } return(outputFile); }
/// <summary> /// This method will extract and save the data from the given <paramref name="storage"/> node to the <paramref name="outputFolder"/> /// </summary> /// <param name="storage">The <see cref="CFStorage"/> node</param> /// <param name="outputFolder">The outputFolder</param> /// <param name="fileName">The fileName to use, null when the fileName is unknown</param> /// <returns>Returns the name of the created file that or null if there was nothing to export within the given <paramref name="storage"/> node.</returns> /// <exception cref="Exceptions.OEFileIsPasswordProtected">Raised when a WordDocument, WorkBook or PowerPoint Document stream is password protected</exception> public string SaveFromStorageNode(CFStorage storage, string outputFolder, string fileName) { Logger.WriteToLog($"Saving CFStorage to output folder '{outputFolder}' with file name {fileName}"); if (storage.TryGetStream("CONTENTS", out var contents)) { Logger.WriteToLog("CONTENTS stream found"); if (contents.Size <= 0) { Logger.WriteToLog("CONTENTS stream is empty"); return(null); } if (string.IsNullOrWhiteSpace(fileName)) { fileName = DefaultEmbeddedObjectName; } const string delimiter = "%DocumentOle:"; var documentOleFileName = GetDelimitedStringFromData(delimiter, contents.GetData()); if (documentOleFileName != null) { if (!documentOleFileName.Equals(string.Empty)) { fileName = Path.GetFileName(documentOleFileName); } contents.SetData(contents.GetData().Skip(delimiter.Length * 2 + documentOleFileName.Length).ToArray()); } return(SaveByteArrayToFile(contents.GetData(), FileManager.FileExistsMakeNew(Path.Combine(outputFolder, fileName)))); } if (storage.TryGetStream("Package", out var package)) { Logger.WriteToLog("Package stream found"); if (package.Size <= 0) { Logger.WriteToLog("Package stream is empty"); return(null); } if (string.IsNullOrWhiteSpace(fileName)) { fileName = DefaultEmbeddedObjectName; } return(SaveByteArrayToFile(package.GetData(), FileManager.FileExistsMakeNew(Path.Combine(outputFolder, fileName)))); } if (storage.TryGetStream("EmbeddedOdf", out var embeddedOdf)) { Logger.WriteToLog("EmbeddedOdf stream found"); // The embedded object is an Embedded ODF file if (embeddedOdf.Size <= 0) { Logger.WriteToLog("EmbeddedOdf stream is empty"); return(null); } if (string.IsNullOrWhiteSpace(fileName)) { fileName = DefaultEmbeddedObjectName; } return(SaveByteArrayToFile(embeddedOdf.GetData(), FileManager.FileExistsMakeNew(Path.Combine(outputFolder, fileName)))); } if (storage.TryGetStream("\x0001Ole10Native", out _)) { Logger.WriteToLog("Ole10Native stream found"); var ole10Native = new Ole10Native(storage); Logger.WriteToLog($"Ole10Native stream format is '{ole10Native.Format}'"); if (ole10Native.Format == OleFormat.File) { return(SaveByteArrayToFile(ole10Native.NativeData, FileManager.FileExistsMakeNew(Path.Combine(outputFolder, ole10Native.FileName)))); } Logger.WriteToLog("Ole10Native is ignored"); return(null); } if (storage.TryGetStream("WordDocument", out _)) { Logger.WriteToLog("WordDocument stream found"); // The embedded object is a Word file if (string.IsNullOrWhiteSpace(fileName)) { fileName = "Embedded Word document.doc"; } return(SaveStorageTreeToCompoundFile(storage, FileManager.FileExistsMakeNew(Path.Combine(outputFolder, fileName)))); } if (storage.TryGetStream("Workbook", out _)) { Logger.WriteToLog("Workbook stream found"); // The embedded object is an Excel file if (string.IsNullOrWhiteSpace(fileName)) { fileName = "Embedded Excel document.xls"; } Excel.SetWorkbookVisibility(storage); return(SaveStorageTreeToCompoundFile(storage, FileManager.FileExistsMakeNew(Path.Combine(outputFolder, fileName)))); } if (storage.TryGetStream("PowerPoint Document", out _)) { Logger.WriteToLog("PowerPoint Document stream found"); // The embedded object is a PowerPoint file if (string.IsNullOrWhiteSpace(fileName)) { fileName = "Embedded PowerPoint document.ppt"; } return(SaveStorageTreeToCompoundFile(storage, FileManager.FileExistsMakeNew(Path.Combine(outputFolder, fileName)))); } return(null); }