【问题标题】:Loop through sub directories in directory遍历目录中的子目录
【发布时间】:2016-01-22 15:13:50
【问题描述】:

我有一个目录“文件夹”,其中包含许多子目录。在每个子目录中都有许多图像。我想遍历“文件夹”目录中的子目录,然后遍历每个目录中的所有图像以将图像导出到 Excel,并将每个子目录中的图像放在一个 Excel 工作表中。

例如如果我有十个子目录,我应该有一个 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#循环遍历每个子目录下的所有图片?

【问题讨论】:

  • 你遇到了什么错误?
  • 嗨@Micky,我在这一行收到错误:'foreach(subdir 中的字符串 img)',错误是“无法将 char 转换为字符串”。
  • 这可能会给你一些想法:stackoverflow.com/questions/29991439/…
  • 您可能想要考虑在您的 Web 应用程序与之通信的单独服务中执行此类操作。 Web 应用在底层 OS 系统中的范围应该是有限的。
  • @CallumLinington 这取决于。有些人喜欢折叠层。

标签: c# asp.net excel directory subdirectory


【解决方案1】:

Janne Matikainen 答案是正确的,但您需要知道如何在您的代码中进行修改...

首先更改您的代码这一行

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

到

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

其次,您需要在您的子文件夹路径中搜索文件,这是您的

foreach (string subdir in filesindirectory)

subdir 是您的目录路径。

只需执行与获取文件相同的操作即可

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

完成 foreach 子目录后

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

重置它,因为您正在增加为每个工作表生成动态行。
然后你在新工作表上,你没有重置它。
它将按照上一张表继续计数。

要获取文件夹名称,您可以通过拆分轻松获取它。
在创建工作表之前,请按照以下步骤操作。

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

记笔记如果文件夹名称包含一些符号,它可能无法将其设置为excel工作表,并且名称不能太长。
请确保您替换为 Excel 工作表的支持符号

【讨论】:

  • 嗨@Nic,感谢您的帮助!我已经尝试过您的解决方案,但图像出现在 1 个 excel 工作表上,而不是所有 excel 工作表上。您知道如何将每个子目录中的图像导出到每个 Excel 电子表格中吗?例如10 个子目录将在 1 个 excel 工作簿中包含 10 个 excel 工作表,谢谢。
  • @FeliciaSoh 完成 subDirectories 的 foreach 后,请退回您的 count1 = 0;。应该从我看到的图像中修复它,您的图像已导入工作表但位于不同的行中。更新答案
  • 嗨@Nic,感谢您的帮助,它的工作原理!顺便说一句,你介意向我解释为什么我需要将 count1 重置为 0 吗?谢谢!:)
  • 嗨@Nic,对不起,我在这里遇到了最后一个问题,你知道如何将每个子目录名称设置为每个 Excel 工作表名称吗?
  • 嗨@Nic,当我尝试将图像添加到excel中并尝试删除包含图像的目录时,它给了我以下错误:“进程无法访问文件image1.png' 因为它正被另一个进程使用。”当我将图像导出到 excel 时,您知道如何关闭 C# 中正在使用的图像文件吗?
【解决方案2】:

这应该列出从 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);
    }
}

【讨论】:

  • 嗨@Janne Matikainen,感谢您的解决方案,但这适用于窗口应用程序吗?抱歉,如果我的帖子不清楚,我正在开发一个网络应用程序。
  • 它用于控制台应用程序,但您可以为您的 Web 应用程序复制 ListFiles() 方法。除了 Console.WriteLine 部分之外,没有什么具体的应用程序类型 :)
  • 编辑了我的答案以完全按照您的意愿实现。
  • @Janne Matikainen 我认为您的第一个 worksheet 将是空的。由于subdirectory里面的图片
  • 嗨@Janne Matikainen,感谢您的帮助!我已经解决了这个问题:)
【解决方案3】:

Directory.GetFiles(dir) 返回 dir 中的所有文件,不包括文件夹 你应该使用 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);
        }
    }
}

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      相关资源
      最近更新 更多