2015-10-23 4 views
1

У меня есть папка «Папка» со многими подкаталогами внутри этого каталога. Внутри каждого подкаталога есть много изображений. Я хочу перебирать подкаталоги в каталоге «Папка», а затем перебирать все изображения в каждом каталоге, чтобы экспортировать изображения в Excel, с изображениями из каждого подкаталога на одном листе Excel.Loop через подкаталоги в каталоге

См., Например, если у меня есть десять подкаталогов, у меня должна быть одна книга Excel с десятью листами Excel, тогда на каждом листе Excel будут изображения из каждого подкаталога.

Это то, что я пытался, но только образы появлялись на Worksheet1 вместо всех рабочих листов:

public void ExportToExcel() 
     { 
      //for export 
      ExcelPackage objExcelPackage = new ExcelPackage(); //create new workbook 

      string[] filesindirectory = Directory.GetDirectories(Server.MapPath("~/Folder")); 
      int count = 0; 
      int count1 = 0; 
      int x = 25; 
      int finalValue = 0; 

      foreach (string subdir in filesindirectory) 
      {      
       count++; 
       ExcelWorksheet ws = objExcelPackage.Workbook.Worksheets.Add("Worksheet" + count); //create new worksheet 

      foreach (string img in Directory.GetFiles(subdir)) 
      { 
       count1++; 
       System.Web.UI.WebControls.Image TEST_IMAGE = new System.Web.UI.WebControls.Image(); 
       System.Drawing.Image myImage = System.Drawing.Image.FromFile(img); 
       var pic = ws.Drawings.AddPicture(count1.ToString(), myImage); 
       // Row, RowoffsetPixel, Column, ColumnOffSetPixel 
       if (count1 > 1) 
       { 
        pic.SetPosition(finalValue, 0, 2, 0); 
        finalValue += (x + 1); // Add 1 to have 1 row of empty row 
       } 
       else 
       { 
        pic.SetPosition(count1, 0, 2, 0); 
        finalValue = (count1 + x) + 1; // Add 1 to have 1 row of empty 
       } 
      } 
      } 

      var filepath = new FileInfo(@"C:\Users\user\Desktop\Test\" + datetime.ToString("dd-MM-yyyy_hh-mm-ss") + ".xlsx"); 
      objExcelPackage.SaveAs(filepath); 
     } 

Как Переберите каждого подкаталогов в каталоге, а затем цикл через все изображения от каждого суб с помощью C#?

+1

Какая ошибка у вас возникла? – MickyD

+0

hi @Micky, я получаю ошибку на этой строке: «foreach (string img in subdir)», ошибка «не может преобразовать символ в строку». –

+0

Это может дать некоторую идею: http://stackoverflow.com/questions/29991439/cannot-convert-type-char-to-string –

ответ

4

Janne Матикайнен ответ правильный, но вы должны знать, как изменить в коде ...

Во-первых изменить код этой строки

string[] filesindirectory = Directory.GetFiles(Server.MapPath("~/Folder")); 

в

string[] filesindirectory = Directory.GetDirectories(Server.MapPath("~/Folder")); 

Во-вторых вам нужно искать файл в суб путь к папке, которая является вашим

foreach (string subdir in filesindirectory) 

подкаталог ваш путь для каталога.

Просто сделай назад то же самое, что вы сделали, чтобы получить файлы

foreach (string img in Directory.GetFiles(subdir)) 

После того, как вы закончите Foreach подкаталоге

foreach (string img in Directory.GetFiles(subdir)) 
{ 
    // Your Code 
} 
// Reset the Count1 
count1 = 0; 

сбросить его, потому что вы увеличиваете для генерации динамического ряда для каждый лист.
Затем вы на новом листе, и вы не сбросили его.
Он будет продолжать отсчет в соответствии с предыдущим листом.

Чтобы получить имя папки, вы можете легко получить ее с помощью split.
Прежде чем создать рабочий лист, выполните следующие действия.

string[] splitter = subdir.Split('\\'); 
string folderName = splitter[splitter.Length - 1]; 

делать заметки если FOLDERNAME содержит некоторый символ может не в состоянии установить его, чтобы преуспеть рабочий лист, а также имя не может быть слишком длинным.
Пожалуйста, убедитесь, что вы замените поддерживаемом символ для первенствовать лист

+0

hi @Nic, спасибо за вашу помощь! Я пробовал ваше решение, но изображения появились на 1 листе excel, а не на всех листах excel. Вы знаете, как я могу экспортировать изображения из каждого подкаталога в каждую таблицу Excel? Напр. Спасибо. 10 подкаталогов будут иметь 10 таблиц excel в 1 книге Excel. –

+1

@FeliciaSoh После того, как вы закончите 'foreach' для ** subDirectories **, верните свой' count1 = 0; '. Должен исправить это из того, что я вижу, что ваш образ импортирован на рабочий лист, но находится на разных строках. Обновленный ответ – Nic

+0

привет @Nic, спасибо за вашу помощь! Кстати, не возражаете ли вы объяснить мне, почему мне нужно сбросить count1 на 0? Спасибо! :) –

4

Это должно содержать список всех файлов, начинающихся с C: \ Images и проходящих через все поддиры и их поддиректории.

public void ExportToExcel() 
{ 
    //for export 
    var objExcelPackage = new ExcelPackage(); //create new workbook 

    this.ListFiles(objExcelPackage, 0, Server.MapPath("~/Folder")); 

    var filepath = new FileInfo(@"C:\Users\user\Desktop\Test\" + datetime.ToString("dd-MM-yyyy_hh-mm-ss") + ".xlsx"); 
    objExcelPackage.SaveAs(filepath); 
} 

public void ListFiles(ExcelPackage objExcelPackage, int worksheetIndex, string path) 
{ 
    var imageCount = 0; 
    var x = 25; 
    var finalValue = 0; 

    var files = Directory.GetFiles(path).Select(s => new FileInfo(s)); 

    if (files.Any()) 
    { 
     //create new worksheet 
     var ws = objExcelPackage.Workbook.Worksheets.Add("Worksheet" + (++worksheetIndex)); 

     foreach (var file in files) 
     { 
      imageCount++; 

      var TEST_IMAGE = new System.Web.UI.WebControls.Image(); 
      var myImage = System.Drawing.Image.FromFile(img); 
      var pic = ws.Drawings.AddPicture(imageCount.ToString(), myImage); 

      // Row, RowoffsetPixel, Column, ColumnOffSetPixel 
      if (imageCount > 1) 
      { 
       pic.SetPosition(finalValue, 0, 2, 0); 
       finalValue += (x + 1); // Add 1 to have 1 row of empty row 
      } 
      else 
      { 
       pic.SetPosition(imageCount, 0, 2, 0); 
       finalValue = (imageCount + x) + 1; // Add 1 to have 1 row of empty 
      } 
     } 
    } 

    foreach (var dir in Directory.GetDirectories(path)) 
    { 
     this.ListFiles(objExcelPackage, worksheetIndex, dir); 
    } 
} 
+0

привет @Janne Matikainen, спасибо за ваше решение, но это для оконного приложения? Извините, если я не понимаю в своем посте, я работаю над веб-приложением. –

+0

Это консольное приложение, но вы можете просто скопировать метод ListFiles() для вашего веб-приложения. Нет ничего конкретного в том, что это за приложение, за исключением Console.WriteLine part :) –

+0

Отредактировал свой ответ, чтобы точно сделать то, что вы хотели бы достичь. –

1

Directory.GetFiles (реж) возвращает все файлы в реже, без папок вы должны использовать Directory.EnumerateDirectories (Dir)

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 

class Program 
{ 
    private static void Main(string[] args) 
    { 
     try 
     { 
      string dirPath = @"\\archives\2009\reports"; 

      List<string> dirs = new List<string>(Directory.EnumerateDirectories(dirPath)); 

      foreach (var dir in dirs) 
      { 
       Console.WriteLine("{0}", dir.Substring(dir.LastIndexOf("\\") + 1)); 
      } 
      Console.WriteLine("{0} directories found.", dirs.Count); 
     } 
     catch (UnauthorizedAccessException UAEx) 
     { 
      Console.WriteLine(UAEx.Message); 
     } 
     catch (PathTooLongException PathEx) 
     { 
      Console.WriteLine(PathEx.Message); 
     } 
    } 
} 
0

The Composite Pattern подходит для вашей проблемы здесь.

public interface IExcelWorksheetAdapter 
{ 
    //todo: implement this method, here you have everything you need for an image file 
    void AddPicture(FileSystemItem aFile); 
} 

public class FileSystemItem 
{ 
    public virtual string FullPath { get; protected set; } 
    public virtual int Level { get; set; } 
    public virtual string Name 
    { 
     get 
     { 
      if (string.IsNullOrWhiteSpace(FullPath)) return string.Empty; 
      return FullPath.Split('\\').Last(); 
     } 
    } 

    public virtual void Operation(IExcelWorksheetAdapter ws) { } 
} 

public class FolderItem : FileSystemItem 
{ 
    public FolderItem(string fullPath) 
    { 
     Items = new List<FileSystemItem>(); 
     if (!Directory.Exists(fullPath)) return; 

     FullPath = fullPath; 

     var files = Directory.GetFiles(FullPath).Select(p => new FileItem(p) { Level = this.Level + 1 }).ToList(); 
     Items.AddRange(files); 

     var subFolders = Directory.GetDirectories(fullPath).Select(p => new FolderItem(p) {Level = this.Level + 1}).ToList(); 
     Items.AddRange(subFolders); 
    } 

    public List<FileSystemItem> Items { get; set; } 

    public override void Operation(IExcelWorksheetAdapter ws) 
    { 
     Items.ForEach(x => x.Operation(ws)); 
    } 
} 

public class FileItem : FileSystemItem 
{ 
    public FileItem(string path) 
    { 
     if (File.Exists(path)) 
     { 
      FullPath = path; 
     } 
    } 

    public override void Operation(IExcelWorksheetAdapter ws) 
    { 
     ws.AddPicture(this); 
    } 
} 

[TestFixture] 
public class DirectoryCompositeTest 
{ 
    [Test] 
    public void Operation_for_a_directory_files() 
    { 
     var directory = new FolderItem(AppDomain.CurrentDomain.BaseDirectory); 
     directory.Operation(new Sample()); // give your IExcelWorksheetAdapter implementation here. 

    } 
} 

public class Sample : IExcelWorksheetAdapter 
{ 
    public void AddPicture(FileSystemItem aFile) 
    { 
     Console.WriteLine(Indent(aFile.Level) + aFile.Name); 
    } 

    private string Indent(int level) 
    { 
     string result = ""; 
     for (int i = 0; i < level; i++) 
     { 
      result += "-"; 
     } 
     return result; 
    } 
}