Loop through sub directories in directory

2019-02-14 16:00发布

I have a directory 'Folder' with many subdirectories inside this directory. Inside every subdirectory there are many images. I want to loop through subdirectories in the 'Folder' directory, then loop through all images in every directory to export the images out to Excel, with images from each subdirectory in one Excel worksheet.

For e.g. if I have ten subdirectories, I should have one Excel workbook with ten Excel worksheets, then in each Excel worksheet there will be images from each subdirectory.

This is what I have tried but images only appeared on Worksheet1 instead of all the worksheets:

   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);
        }

How to loop through each sub directories in a directory, then loop through all images from each sub directory using C#?

4条回答
太酷不给撩
2楼-- · 2019-02-14 16:15

This should list all files starting from C:\Images and go through all subdirs and their subdirs as well.

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);
    }
}
查看更多
看我几分像从前
3楼-- · 2019-02-14 16:16

Janne Matikainen answer is correct but you need to know how to modify in your code...

First change your code this line

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

to

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

Secondly you need to search file in your sub folder path which is your

foreach (string subdir in filesindirectory)

subdir is your path for your directory.

Just do back the same thing what you did to get the files

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

After you finish the foreach subdirectory

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

Reset it because you are increasing for dynamic row generating for each sheet.
Then you at new sheet and you didn't reset it.
It will continue the count as per previous sheet.

To get the folder name you can easily get it by split.
Before you create the worksheet you do as per below.

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

Take NOTES if the folderName contain some symbol it might not able to set it to excel worksheet and also the name cannot be too long.
Please ensure that you replace with supportable symbol for excel worksheet

查看更多
混吃等死
4楼-- · 2019-02-14 16:17

Directory.GetFiles(dir) returns all files in dir, without folders you should use 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);
        }
    }
}
查看更多
别忘想泡老子
5楼-- · 2019-02-14 16:20

The Composite Pattern fits your problem here.

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;
    }
}
查看更多
登录 后发表回答