0

I have got images in the 'images' folder named as such;

100.jpg
200.jpg
and on..

I have an excel sheet that has values in the first (A) and second (B) column as such;

A    B
100  101
200  102
and on..

I tried writing a small program that renames the image files looking into Column A, and renaming it with Column B.

So once the program ran, my images folder would have images named; 101.jpg 102.jpg

Here is my attempt;

var express = require('express');
var path = require('path');
var fs = require('fs');
var Excel = require('exceljs');

var app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.disable('etag');
const testFolder = './images/';
var workbook = new Excel.Workbook(); 
var container;
var unprocfile;
var str;
var renamer;

var runner = 1;
fs.readdir(testFolder, (err, files) => {
  files.slice(1).forEach(file => {
      console.log('Entering foreach of files');
    unprocfile = file;
    str = unprocfile.substr(0, unprocfile.lastIndexOf("."));
    console.log('Name of the file' + str);
    workbook.xlsx.readFile('/Users/Mesam/Documents/renameimages/file.xlsx')
        .then(function() {
            var worksheet = workbook.getWorksheet('Sheet1');
            worksheet.eachRow( function(row, rowNumber) {
             container = row.values;
             // console.log(  typeof container);
             console.log('Entering foreach of Row');
             console.log('Value of 1st column' + row.values[1]);
             if (row.values[1] == str) {
                console.log('If name of file matched value of 1st column' + str + row.values[1]);
              renamer = row.values[2];
              console.log('Renamer var value '+ renamer);
              fs.rename('/Users/Mesam/Documents/renameimages/images/' + file, '/Users/Mesam/Documents/renameimages/images/' + renamer+ '.jpg', function(err, success){
                if (err){console.log(err)};
             });
             }
            });
        });
  })
});
// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};


  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

Here is the output of DEBUG CONSOLE;

Entering foreach of files
app.js:33
Name of the file100
app.js:36
Entering foreach of files
app.js:33
Name of the file200
app.js:36
Entering foreach of Row
app.js:43
Value of 1st column100
app.js:44
Entering foreach of Row
app.js:43
Value of 1st column200
app.js:44
If name of file matched value of 1st column200200
app.js:46
Renamer var value 202
app.js:48
Entering foreach of Row
app.js:43
Value of 1st column300
app.js:44
Entering foreach of Row
app.js:43
Value of 1st column100
app.js:44
Entering foreach of Row
app.js:43
Value of 1st column200
app.js:44
If name of file matched value of 1st column200200
app.js:46
Renamer var value 202
app.js:48
Entering foreach of Row
app.js:43
Value of 1st column300

Now the idea is, for each file, it has to loop through all the rows it finds on the excel, compare the value of first-row column A if it matches, renames the file with the Column B value.

However, the debug console shows me that foreach of files executes without running the inner foreach of the excel. Hence the output of the program is only 1 image is left in my folder with correct name 202.jpg.

EDIT1; Useful info; I am working on MAC, so the reason to splice(1) is to skip the DS_Store file. By default, the system creates that hidden file.

The output of console.log(file); by itself is 100.jpg 200.jpg with splice(1)

The output of console.log(row.values) is

[Null, 100, 101]
[Null, 200, 202]

No idea why I got Null there but the code was written in a way to ignore it. Hence row.values[1] ..

mysamza
  • 387
  • 1
  • 6
  • 22
  • Please create a small example with a simple array & `foreach` to illustrate your issue. – palaѕн Feb 20 '20 at 16:42
  • @palaѕн added more useful comments related to how the array looks like. – mysamza Feb 20 '20 at 16:51
  • the reason it is 'skipping' your loop is because its actually reading __all__ your files in parallel and then renaming all the images in parallel. So your logs are a complete mess and look like its skipping stuff but its actually doing it.. just not when you expect it. I would suggest you [learn more about Promises and async](https://jrsinclair.com/articles/2019/how-to-run-async-js-in-parallel-or-sequential/) – japrescott Feb 20 '20 at 17:06
  • Making the minimum amount of code to illustrate your problem will actually show _you_ the problem/solution 8/10 times. – Josh Wulf Feb 20 '20 at 17:13
  • You don't have to read `file.xlsx` inside the directory loop each time, read it outside and build an object like `{ [oldName] => [newName] }`. The you can read the directory, do a simple `if (filename in nameMap)` then change name. – ksankar Feb 20 '20 at 17:47
  • @ksankar Yes.. This gave me the idea. Will build the object of off the sheet prior and in a for loop that iterates over the files will compare this object. Thanks! – mysamza Feb 20 '20 at 18:04

0 Answers0