I want to create a list of all the .xlsx files on my computer and the number of rows in them.
What is the best way to get the # of rows in each .xlsx file? I'm on Mac OSX Yosemite (if it's relevant). The answer can be in any language.
You can do it with PHP and Spout (https://github.com/box/spout).
The code would look something like this:
use Box\Spout\Reader\ReaderFactory;
use Box\Spout\Common\Type;
// This is the root directory you want to list the XLSX files of
// CHANGE IT !!
$rootPath = '/path/to/root/directory';
// this will read the XLSX file at the given path and return the number of rows for the file
function getNumRows($xlsxPath) {
$numRows = 0;
$reader = ReaderFactory::create(Type::XLSX);
$reader->open($xlsxPath);
foreach ($reader->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
$numRows++;
}
}
$reader->close();
return $numRows;
}
// This will recursively go through the root folder and all its subfolders
$directoryIterator = new \RecursiveDirectoryIterator($rootPath, RecursiveDirectoryIterator::SKIP_DOTS);
$recursiveIterator = new \RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::SELF_FIRST);
foreach ($recursiveIterator as $fileInfo) {
if (strtolower($fileInfo->getExtension()) === 'xlsx') {
$xlsxPath = $fileInfo->getPathname();
$numRows = getNumRows($xlsxPath);
// store the number of rows for the file somewhere
}
}
Related
I'm exporting some Data from a DB and I want to have the 2 columns that I generate Tab separated.
I've already tried to use implode after my fputcsv but it always appears comma separated. Also tried changing my separator (,) to some other character, but a comma is always printed in the CSV.
This is the function that I'm using for it.
public function ResearchExport(Request $request)
{
//Export ProductID and KitID of all the Kits created from the given date to the actual moment
$TubeAddDate = $request->input('TubeAddDate');
$select = DB::table('tubes')->select('TubeBarcodeID', 'ActivationCode')->where('LOG_important', '2')->whereBetween('TubeAddDate', array($TubeAddDate, NOW()))->get();
$tot_record_found=0;
if (count($select)>0) {
$tot_record_found=1;
$CsvData=array('TubeBarcodeID,ActivationCode');
foreach ($select as $value) {
$CsvData[]=$value->TubeBarcodeID.",".$value->ActivationCode.;
}
$filename=date('Y-m-d').".csv"; //stores the file with the date of today as name
$file_path=storage_path().'/'.$filename;
$file = fopen($file_path, "w+");
foreach ($CsvData as $exp_data) {
fputcsv($file, explode(",", $exp_data));
}
fclose($file);
return response()->download($file_path, $filename);
}
return view('InsertForms/download', ['record_found' =>$tot_record_found]);
}
At the moment I'm getting this as output
TubeBarcodeID,ActivationCode
FF01111112,IKG5G-B0FIZ
FF0111113,6XMP8-760Y3
but I expect something tab separated in the CSV like this
TubeBarcodeID ActivationCode
FF01111112 IKG5G-B0FIZ
FF0111113 6XMP8-760Y3
So I actually just solved thanks to one of the commentaries that pointed out my error.
I just had to change my .csv to .xls and then override the third parameter of fputcsv with a "\t".
$filename=date('Y-m-d').".xls"; //stores the file with the date of today as name
$file_path=storage_path().'/'.$filename;
$file = fopen($file_path, "w+");
foreach ($CsvData as $exp_data) {
fputcsv($file, explode(",", $exp_data), "\t");
}
I'm working with Magento 2, I need to read a file through ftp connection. I can login to ftp but I cannot read the csv file. What I did so far (I cut all the unnecessary parts):
use Magento\Framework\File\Csv;
use Magento\Framework\Filesystem\Io\Ftp;
class MyClass {
protected $_csvprocessor;
protected $_ftp;
public function __construct(Csv $csvprocessor, Ftp $ftp) {
$this->_csvprocessor = $csvprocessor;
$this->_ftp = $ftp;
}
public function getCsv() {
$conn = $this->_ftp->open($params); // this works, I can successfully login to ftp
$filecsv = $this->_ftp->read($remotepathtofile); // this gets me the file but it is a string, not an array with the csv data
$this->_csvprocessor->getData($remotepathtofile); // this doesn't work with remote file, only with local path (eg: magentoroot/var/import/file.csv)
}
}
How can I read the csv as an array, as $this->_csvprocessor->getData() would return, but from remote file instead of local?
You need to parse the csv string. Try using the function "fgetcsv". See http://php.net/manual/en/function.fgetcsv.php.
Below the code, you can use to read CSV file an array
use Magento\Framework\App\Bootstrap;
include('app/bootstrap.php');
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$objectManager1 = Magento\Framework\App\ObjectManager::getInstance();
$directoryList = $objectManager1->get('\Magento\Framework\App\Filesystem\DirectoryList');
$path = $directoryList->getPath('media');
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
$myarray = glob("Book1.csv");
usort($myarray, create_function('$a,$b', 'return filemtime($a) - filemtime($b);'));
if(count($myarray)){
/*This will create an array of associative arrays with the first row column headers as the keys.*/
$csv_map = array_map('str_getcsv', file($myarray[count($myarray)-1]));
array_walk($csv_map, function(&$a) use ($csv_map) {
$a = array_combine($csv_map[0], $a);
});
array_shift($csv_map); # remove column header
/*End*/
$message = '';
$count = 1;
foreach($csv_map as $data){
your code....
}
Hope this will help you enjoy...
You can dump the server file to your local.
$filecsv = $this->_ftp->read($remotepathtofile, $destinationFilePath);
where $destinationFilePath is local file path.
Then use that local file.
I want to upload files to my server with CodeIgniter, and I need to change the file name dynamically with some random numbers.
But before changing the name I also need the original name to store it in the database. How can I do that?
Depending on which browsers you support you can use some of the functional extensions to the array prototype. Namely filter and every.
var arr = [[1,null,null],[1,null,null],[1,5,2],[null,null,null],[null,1,null],[1,2,3]];
var filtered = arr.filter(function(x){
return x.every(function(value){
return value != undefined;
});
});
console.log(filtered);
Just add these arrays to new one:
$newArray = [
$oldArray[4],
$oldArray[5],
$oldArray[7],
$oldArray[8],
$oldArray[10],
$oldArray[11],
];
EDIT
for dynamic, use something like that (not tested):
var newArray = [];
var oldArray = [/* ... */];
function addElement(eId){
newArray.push(oldArray[eId]);
}
$.each(SomeRandomArrayIndexes, function(k, eId){
addElement(eId);
});
I'm trying to use DotNetZipLib-DevKit-v1.9 in my MVC3 Project to extract the files to a specific folder.
What i want is -- How to add multiple entries in zip.SelectEntries method.
Here is my code in controller action:
public ActionResult ExtractZip(string fileName, HttpPostedFileBase fileData)
{
string zipToUnpack = #"C:\Users\Public\Pictures\Sample Pictures\images.zip";
string unpackDirectory = System.IO.Path.GetTempPath();
using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
{
// here, we extract every entry, but we could extract conditionally
// based on entry name, size, date, checkbox status, etc.
var collections = zip1.SelectEntries("name=*.jpg;*.jpeg;*.png;*.gif;");//This shows `0` items in collections
foreach (var item in collections)
{
item.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}
return Json(true);
}
In this line var collections = zip1.SelectEntries("name=*.jpg;*.jpeg;*.png;*.gif;"); if i specify only single extension ,it works fine
ex:
var collections = zip1.SelectEntries("name=*.gif"); this works good
I've also seen SelectEntries method here, but it doesn't help though
How to add multiple entries ?
Finally i could answer my own question.
Inorder to select multiple entries we need to use OR and to select multiple entries use the following code:
var collections = zip1.SelectEntries("(name=*.jpg) OR (name=*.jpeg) OR (name=*.png) OR (name=*.gif)");
foreach (var item in collections)
{
item.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
I'm trying to get a specific folder in outlook with c#. Someone else had the same issue here Using Outlook API to get to a specific folder but when using the Folders collection I'm not sure how to get through the folders collection. I mean, I've looked at the type of object that the Folders collection returns and it looks like it's a Folders object. But when I try to use that in a loop it gives me an invalid cast exception. I also hoped I could use the GetFolderFromID method to give it the string name of the folder but that doesn't want to work either... but I also can't find an example of how to use it so I'm not sure I'm coding it correctly. Here's an example of what I tried. Anyone know how to get the Processed folder which is on the same level as the Inbox folder? Thanks.
MAPIFolder oProcessed = null;
foreach (var folder in oNS.Folders)
if (folder.ToString() == "Processed")
{
oProcessed = (MAPIFolder)folder;
}
if (oProcessed == null)
throw new Exception("Missing processed folder.");
you need to get hold of the root level mailbox folder
Outlook.MAPIFolder rootFolder= Application.Session.DefaultStore.GetRootFolder();
Then loop through the rootFolder folders collection check in the names
Outlook.MAPIFolder processedFolder = null;
foreach (Outlook.MAPIFolder folder in rootFolder.Folders)
{
if (folder.Name == "Processed")
{
processedFolder = folder;
break;
}
}
Check out http://msdn.microsoft.com/en-us/library/bb176810.aspx to get you head round the API.
Marcus
Outlook.MAPIFolder rootFolder = Application.Session.DefaultStore.GetRootFolder();
var processedFolder = rootFolder.Folders.Cast<Outlook.MAPIFolder>().Where(r => r.Name == "Processed").FirstOrDefault();
This is an inept translation from VBA, but may offer some ideas, seeing you have no answers as yet. In VBA, it is best to get the parent folder of Inbox and to look in that for folders at the same level.
Microsoft.Office.Interop.Outlook._Folders oFolders;
Microsoft.Office.Interop.Outlook.MAPIFolder oPublicFolder =
olNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox).Parent;
//Folders at Inbox level
oFolders = oPublicFolder.Folders;
foreach (Microsoft.Office.Interop.Outlook.MAPIFolder Folder in oFolders)
{
string foldername = Folder.Name;
if (foldername == "Test")
Console.Write(Folder.Name);
}
If you have the folder path as a string, you can use this function:
private MAPIFolder GetFolder(string folderPath, Folders folders)
{
string dir = folderPath.Substring(0, folderPath.Substring(4).IndexOf("\\") + 4);
try
{
foreach (MAPIFolder mf in folders)
{
if (!(mf.FullFolderPath.StartsWith(dir))) continue;
if (mf.FullFolderPath == folderPath) return mf;
else
{
MAPIFolder temp = GetFolder(folderPath, mf.Folders);
if (temp != null)
return temp;
}
}
return null;
}
catch { return null; }
}