Консультация № 179677
07.08.2010, 10:46
0.00 руб.
0 12 2
Здравствуйте, у меня такая задача: мне нужно из ячеек файла excel копировать(или обновлять) данные в соответствующие ячейки БД Mysql, в файле будут такие колонки:
номер,название,категория,цена1,цена2,цена3,цена4,цена5,цена6,цена7,цена8
И все эти значения у меня находятся по разным таблицам в базе, я думаю, что это повышает сложность задачи.
Говорят, что это можно реализовать с помощью phpmyadmin, но большинство цен дробные (90,45).
Если не получится реализовать это какими-либо программными средствами, то мне придется присать скрипт, я изучаю php, вот буду писать его на Php.
Подскажите пожалуйста технологию работы скрипта или пример, я думаю, что это легко (относительно), - загрузить файл .csv на сервер и запустить скрипт, считать оттуда данные и скопировать в соответствующие ячейки. Но не знаю как это реализовать.
Я смотрел в книгах по Php работу с файлами csv, но там только преобразование его в Html.

Обсуждение

Неизвестный
07.08.2010, 21:29
общий
это ответ
Здравствуйте, Исаак Моисеевич.
Дня начала несколько просто общих замечаний:
а) дробность цен на сложность задачи не влияет;
б) файл в формате csv - это просто текстовый файл, то есть никаких проблем в работе с ним нет.
Не совсем понятно, на какой операционной системе работает сервер и насколько часто возникает задача такого переноса данных, то есть до какой степени ее нужно автоматизировать.
В целом же я вижу два возможных направления, как действовать. Буду предполагать, что Вы сами руками экспортируете данные из excel-файла в файл в формате csv, а затем загружаете его на сервер.
Вариант 1. Основной упор - на средства базы данных.
MySQL поддерживает импорт данных из файлов csv. Импортировать данные можно разными способами - SQL-командой или с помощью PhpMyAdmin. Последний вариант подразумевает, что Вам это придется делать вручную, кроме того, PhpMyAdmin должен быть установлен на сервере. Нужен он там или нет - решать Вам. Возможно, Вам понравятся какие-то его возможности. А может быть все наоборот и Вы не захотите ставить лишнего на сервер. Факт в том, что можно обойтись и без PhpMySQL и загружать данные из файла SQL-командой, причем это можно делать и автоматически. Да, забыла сказать. Этот вариант предполагает, что в БД создается некая временная таблица для хранения именно данных из файла. Вариант загрузки с помощью SQL найти несложно, например - вот. Как импортировать данные в PhpMyAdmin, думаю, разберетесь, там достаточно понятный веб-интерфейс. Итак, первый шаг пройден - есть временная таблица с данными из файла. Теперь шаг второй - просто с помощью запросов UPDATE обновляете данные в Ваших таблицах, забирая новые данные из этой временной таблицы. Задача решена.
Вариант 2. Основной упор - на средства скриптового языка. Вам нужно будет написать скрипт, достаточно несложный. Алгоритм работы скрипта: открываем csv-файл, считываем его построчно, для каждой строки определяем разделитель (";") и данные между разделителями записываем в переменные, затем выполняем несколько запросов к БД и обновляем таблицы этими новыми данными, как только все строчки пройдены - закрываем файл. На php я не пишу, но на perl это действительно все просто делается. Может быть, Вам стоит присмотреться и к perl. ;)
Если будут вопросы - обращайтесь. И по работе с SQL, и с написанием скрипта, и вообще любые.
Удачи!
5
Неизвестный
09.08.2010, 10:07
общий
Я использую вот такой класс для загрузки csv
Код:
class csv
{
public $quotes='"';
public $delimiter=",";
function split($str)
{

$entered_quotes=false;
$ind=0;
$res='';
$coll='';
$len=strlen($str);

for($k=0;$k<$len;$k++)
{

if(($str[$k]==$this->delimiter)&($entered_quotes==false))
{
$res[$ind]=$coll;
$ind++;
$coll='';
continue;
};
if(($str[$k]==$this->quotes)&($entered_quotes==false))
{
$entered_quotes=true;
continue;
};
if(($str[$k]==$this->quotes)&($entered_quotes==true))
{
if($k==($len-1))
{
$res[$ind]=$coll;
$ind++;
return $res;
};
if(($k<($len-1))&($str[$k+1]==$this->quotes))
{
$coll.=$str[$k];
$k++;
continue;
};

$entered_quotes=false;
continue;
};
$coll.=$str{$k};
};
$res[$ind]=$coll;

return $res;
}

function join($arr)
{
$res="";
foreach($arr as $e)
{
if($res!=="")$res.=$this->delimiter;
if(strstr($e,$this->delimiter)!==false || strstr($e,$this->quotes)!==false)
$ne=preg_replace('/'.preg_quote($this->quotes).'/',$this->quotes.$this->quotes,$e);
if(isset($ne))$res.=$this->delimiter.$ne.$this->delimiter;
else $res.=$e;
}
return $res;
}
}

использовать примерно так:
Код:
$fd=fopen($file_name,'r');
$csv=new csv;
while($str=fgets($fd))
{
$str_utf8=iconv("cp1251","utf-8",$str);
$values=$csv->split(trim($str));
// собираем и выполняем запрос
}
fclose($fd);
Неизвестный
09.08.2010, 12:44
общий
vladisslav:
Я така понимаю это класс для распарсивания, а не для загрузки
Неизвестный
09.08.2010, 12:51
общий
это ответ
Здравствуйте, Исаак Моисеевич.
По работе с CSV никаких проблем быть не должно(смотрите приложение).


Приложение:
<?php
// Open file
$csvFileHandle = fopen('name_file.csv', 'r');
// Check for errors
if ($csvFileHandle === false) {
echo('Error opening .csv file');
die();
}
// Open connection to mysql
$mysqlHandle = mysql_connect('your host', 'your_user', 'your_password');
// Check for errors
if ($mysqlHandle === false) {
echo('Error connecting to database');
die();
}
// Read from csv file
while ( ($arrayValues = fgetcsv($csvFileHandle)) !== false) {
// Make your inserts to database here. Somethink like this:
$queryResult = mysql_query("insert into `table` (`number`, `naim`, `category`, `price1`, `price2`, `price3`, `price4`, `price5`, `price6`, `price7`, `price8`) VALUES
($arrayValues[0], $arrayValues[1], $arrayValues[2], $arrayValues[3], $arrayValues[4], $arrayValues[5], $arrayValues[6], $arrayValues[7], $arrayValues[8], $arrayValues[9], $arrayValues[10])", $mysqlHandle);
if ($queryResult === false) {
echo('Error inserting row');
var_dump($arrayValues);
}
// Close connection
mysql_close($mysqlHandle);
}
?>
5
давно
Практикант
137657
274
09.08.2010, 16:49
общий
lupus campestris:
lupus campestris, операционная система linux, я бы хостинг назвал, да наверное нельзя тут называть.
Перенос данных будет часто, возможно каждый день. Нужно чтобы менеджер импортировал данных из программы БИС в формате excel, я так понял, что надо будет сохранять в формате .csv, и чтобы он загрузил на сервер этот файл и запустил операцию копирования данных из файла в БД MYSQL.
Можно создать постоянную таблицу для этих целей, назвать ее temp, phpMyadmin есть.
Жалко что я перл не учу пока, ну попробую для начала первый вариант.

Ivol84, почему в вашем примере процедура соединения с сервером с логином и паролем?

Леуткин Дмитрий Николаевич, что это за класс? Это на Javascript?
Неизвестный
10.08.2010, 12:49
общий
Исаак Моисеевич:
Хостинг не важен, в общем. Главное, что там все есть для работы.
давно
Практикант
137657
274
11.08.2010, 08:42
общий
lupus campestris:
Я еще забыл написать: каждое поле с названием содержит гиперссылку, из нее надо загрузить картинку в папку с картинками и чтобы они потом отображались на странице.
Неизвестный
12.08.2010, 12:52
общий
Исаак Моисеевич:
Загрузку картинок можно сделать обычным shell-скриптом.
Например, Ваш текстовый файл (csv) содержит такие записи:
1;http://img.lenta.ru/articles/2010/08/12/rusbul/pic003.jpg;smth
2;http://img.lenta.ru/articles/2010/08/12/rusbul/pic002.jpg;smth2
3;http://img.lenta.ru/articles/2010/08/12/rusbul/picture.jpg;smth3
То есть ссылка идет вторым полем.
Тогда можно так собирать картинки:
#!/bin/bash
mkdir ./temp_jpg
cd ./temp_jpg
for a in $(cat ../file.csv|cut -f 2 -d ";"); do
wget $a
done
cd ..
mv ./temp_jpg/* your_dir
rm -rf ./temp_jpg
давно
Практикант
137657
274
12.08.2010, 14:22
общий
И на хостинге будет работать этот скрипт?
А как картинки будут загружаться? Они ведь находятся на другом сайте и в файле excel они в виде ссылок.
Неизвестный
12.08.2010, 14:26
общий
Исаак Моисеевич:
А почему он не должен работать? Если сервер уже к интернету подключен, то загружать можно что угодно.
Вы можете попробовать сами команду:
wget <ссылка на какую-то картинку в интернете>

Или Вы имеете в виду, что там еще "a href="?
Можете выложить строчку из файла? Я Вам напишу, как вырезать точную ссылку на картинку.
давно
Практикант
137657
274
12.08.2010, 16:40
общий
Вот я выложил файл, там где две первые строки, это строки из файла, в котором находится ссылка на картинку, потом две строки это из файла, из которого надо взять все значения и записать в базу данных, я не представляю только как можно сделать, чтобы потом каждая запись соответствовала своей картинке и чтобы она отображалась.
http://slil.ru/29556603
Неизвестный
13.08.2010, 18:59
общий
Исаак Моисеевич:
О, наконец-то нашла, как это сделать!
Открываем экселевский файл, который с ссылками. Нажимаем ALT+F11. Вводим код и сохраняем:
Sub NoHyperlinks()
Dim c As Range
For Each c In ActiveSheet.UsedRange.Cells
If c.Hyperlinks.Count > 0 Then c.Value = c.Hyperlinks.Item(1).Address
Next c
End Sub
Открываем снова лист с формулами, нажимаем ALT+А8, выбираем нашу функцию (у меня - Книга1.xls!Module1.NoHyperlinks) и нажимаем кнопку Выполнить. Все, ссылки стали обычными.
Потом делаем экспорт в csv и т.д.
А сверять записи видимо по номенклатурному номеру нужно.
Форма ответа