Имя: Пароль:
1C
1С v8
Сжатие xls файла для отправки по почте.
,
0 dkonakov
 
22.05.13
11:54
Добрый день! Имеется УТ 10.2, формируется прайс с картинками через следующий код:
<code>
Картинка = Номенклатура.ОсновноеИзображение.Хранилище.Получить();
Строка.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
Cтрока.Рисунки.D1.Имя = "Рисунок";
Cтрока.Рисунки.Рисунок.Верх = 1;                Строка.Рисунки.Рисунок.Высота = 30;
Строка.Рисунки.Рисунок.Ширина = 39;
Строка.Рисунки.Рисунок.Лево = 1;
Строка.Рисунки.Рисунок.ГраницаСлева = Ложь;
Строка.Рисунки.Рисунок.ГраницаСправа = Ложь;
Строка.Рисунки.Рисунок.ГраницаСверху = Ложь;
Строка.Рисунки.Рисунок.ГраницаСнизу = Ложь;
Строка.Рисунки.Рисунок.Картинка = Картинка;
Cтрока.Рисунки.Рисунок.РазмерКартинки = РазмерКартинки.Пропорционально;
</code>
Файл пытаемся сохранить в xls. Файл из 33 картинок получается 1.23 мегабайта. Открываем в OpenOffice, Excel, закрываем, сохраняем, 261 кб.
Читал много тем, но ответа так и не нашел. Как же сжать программно файл xls? Пробовал и через Excel.Application - почему то не работает метод SaveAs. Пробовал через внешнюю компоненту Yoksel, так и не понял, как в ней открыть и сразу сохранить файл.
Коллеги, поделитесь опытом, как уменьшать XLS файл в размере?
1 Privalov
 
22.05.13
11:55
(0) Это куда он картинки девает?
2 dkonakov
 
22.05.13
11:56
(1) Вывод в табличный документ.
3 Sammo
 
22.05.13
12:25
Сожми, и отправляй zip
4 H A D G E H O G s
 
22.05.13
12:29
(2) Сохрани ТабДок в mxl, открой его Akelpad-ом каким нибудь рассово верным и посмотри на херню в тэгах.
5 dk
 
22.05.13
12:34
Для Excel 2003 есть в инете процедура программного сжатия картинок
Для 2007 и выше не нашел, когда нужно было (
6 dkonakov
 
22.05.13
12:37
(3) Не всё так просто, если формировать полный прайс, то это 160 мегобайт. Его попросту не открыть потом.
(4) для чего?
(5) Вашу тему кажется читал, тоже ответа не получили, Вам кстати удалось сжать файл? неважно каким способом.
7 ptiz
 
22.05.13
12:37
У вас так много прайсов, что 1 мегабайт что-то решает?
8 ptiz
 
22.05.13
12:37
тьфу... Так бы и писал сразу. А то "1.23 мб".
9 DS
 
22.05.13
12:42
(0) А не смущает, что файл с 33 картинками весит всего 261 кб?
10 H A D G E H O G s
 
22.05.13
12:43
(6) Посмотреть, что за фигню написала 1С в mxl
11 dkonakov
 
22.05.13
12:45
(8) Это был лишь пример, файл 160 мегобайт попросту не открывается, чтобы его Excel-ем открыть и пересохранить. Причем всему виной - Объект "Рисунок" из 1с, неважно, есть в нем картинка или нету, он занимает место.
(9) Нет, не смущает, а почему должно смущать, картинки мелкие, по 7-10 кб.
12 DS
 
22.05.13
12:46
(11) Тогда, действительно, можно попробовать искать мусор.
13 dkonakov
 
22.05.13
12:47
(12) ну собственно MXL файл весит ровно столько же(261 кб), откуда появляется лишний мегабайт и, главное, как от него избавиться при сохранении?
14 dk
 
22.05.13
12:49
(6) пересохраняю в формате xlOpenXMLWorkbook потом в формате 97-2003
сжимает наполовину примерно
но штатный метод рисунки - сжать до 96 dpi сжимает в 8-12 раз
только вот вызвать его программно не получается
15 dkonakov
 
22.05.13
12:55
(14) Код не покажете? Я новичок, всего месяц в 1с 8. А применить тот же метод через графическую компоненту не пробовали? я сейчас попробую через gflax и вам отпишусь.
16 dk
 
22.05.13
12:59
(15)

Процедура СжатьЭксельФайл(Файл)
   
   Если ПустоеЗначение(Файл) = 1 Тогда
       Сообщить("Не выбран файл!");
       Возврат;
   КонецЕсли;
   
   Если ФС.СуществуетФайл(Файл) = 0 Тогда
       Сообщить("Не найден файл: " + Файл);
       Возврат;
   КонецЕсли;
   
   Попытка
       Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl");
       Скрипт.language="javascript";
       AppExcel=Скрипт.Eval("new ActiveXObject('Excel.Application')");
   Исключение
       Попытка
           AppExcel=СоздатьОбъект("Excel.Application");
       Исключение
           Сообщить("Не удалось открыть Excel");
           Возврат;
       КонецПопытки;
   КонецПопытки;
   
   НовоеИмя1 = КаталогВременныхФайлов() + "temp1_" + _GetPerformanceCounter() +  ".xls";
   ФС.КопироватьФайл(Файл, НовоеИмя1, 0);
   
   Попытка
       Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl");
       Скрипт.language="javascript";
       AppExcel2=Скрипт.Eval("new ActiveXObject('Excel.Application')");
   Исключение
       Попытка
           AppExcel2=СоздатьОбъект("Excel.Application");
       Исключение
           Сообщить("Не удалось открыть Excel");
           Возврат;
       КонецПопытки;
   КонецПопытки;
   
   Попытка
       AppExcel.DisplayAlerts = 0;
       Книга = AppExcel.WorkBooks.Open(НовоеИмя1);
       //Книга.VBProject.VBComponents.Add(1); // добавляем модуль номер 1
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(1, "Sub СжатиеКартинки()");
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(2, "Dim Команда As CommandBarControl");
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(3, "Set Команда = Application.CommandBars.FindControl(ID:=6382)");
       ////Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(4, "Application.SendKeys ""%и~""");
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(4, "Application.SendKeys ""{TAB}""");
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(5, "Application.SendKeys ""{TAB}""");
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(6, "Application.SendKeys ""{TAB}""");
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(7, "Application.SendKeys ""{ENTER}""");
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(8, "Команда.Execute");
       //Книга.VBProject.VBComponents("Module1").CodeModule.InsertLines(9, "End Sub");
       //AppExcel.Run("СжатиеКартинки");
       AppExcel.Visible = 0;
       НовоеИмя2 = КаталогВременныхФайлов() + "temp2_" + _GetPerformanceCounter() +  ".xlsx";
       Книга.SaveAs(НовоеИмя2, 51); // 50 - в формате 2007-2010-го офиса 56 - в формате 97-2003-го офиса
       Книга.Close(0);
       AppExcel.Quit();
       AppExcel2.DisplayAlerts = 0;
       AppExcel2.Visible = 0;
       Книга = AppExcel2.WorkBooks.Open(НовоеИмя2);
       ПараметрыСтр = Книга.Sheets(1).PageSetup;
       Автозум(ПараметрыСтр);
       ПараметрыСтр.RightFooter = "&P";
       ПараметрыСтр.FitToPagesWide = 1;
       ПараметрыСтр.LeftMargin        = AppExcel2.InchesToPoints(0.25);
       ПараметрыСтр.RightMargin    = AppExcel2.InchesToPoints(0.25);
       ПараметрыСтр.TopMargin        = AppExcel2.InchesToPoints(0.75);
       ПараметрыСтр.BottomMargin    = AppExcel2.InchesToPoints(0.75);
       ПараметрыСтр.HeaderMargin    = AppExcel2.InchesToPoints(0.3);
       ПараметрыСтр.FooterMargin    = AppExcel2.InchesToPoints(0.3);    
       Книга.SaveAs(Файл, 56); // 50 - в формате 2007-2010-го офиса 56 - в формате 97-2003-го офиса
       Книга.Close(0);
       ФС.УдалитьФайл(НовоеИмя1);
       ФС.УдалитьФайл(НовоеИмя2);
       Сообщить("Записали файл: " + Файл);
       AppExcel2.Quit();
   Исключение
       Сообщить("Ошибка при записи: " + ОписаниеОшибки());
   КонецПопытки;
   
КонецПроцедуры
17 dkonakov
 
22.05.13
13:07
(16) Спасибо. у gflax есть такие методы.
Преобразователь = Новый COMОбъект("GFLAx.GFLAx");
           Преобразователь.LoadBitmap(ПутьКФайлу);
           Ширина = Преобразователь.Width;
           Высота = Преобразователь.Height;
           // алгоритм пропорционального преобразования разрешения картинки до 300 на 300
           Если Высота > 300 ИЛИ Ширина > 300 Тогда
           НоваяВысота = 300;
           НоваяШирина = Цел((Ширина * НоваяВысота)/Высота);
           Если НоваяШирина < 300 Тогда
               НоваяШирина = 300;
               НоваяВысота = Цел((Высота * НоваяШирина)/Ширина);
           КонецЕсли;
           Преобразователь.Ydpi = 96;
           Преобразователь.Xdpi = 96;
           Преобразователь.Resize(НоваяШирина, НоваяВысота);
           КонецЕсли;
           //
           Преобразователь.SaveFormat = 1;
           Преобразователь.SaveBitmap(ПутьКФайлу);
           Картинка = Новый Картинка(ПутьКФайлу);
18 dk
 
22.05.13
13:13
(17) имхо не поможет
ты меняешь разрешение картинки, но при сохранении в xls твое разрешение сменится обратно на разрешение в Excel
--
Если только попробовать поискать константу в Excel которая отвечает за то, в каком разрешении будут храниться картинки внутри Excel
19 dkonakov
 
22.05.13
13:31
(18) А Yoksel не пробовали? Просто я сейчас прихожу к выводу, что Excel у меня на сервере терминалов не установлен, а значит использовать его не получится. Надо искать другой способ.
20 dk
 
22.05.13
13:34
не пробовал, т.к. сейчас он не установлен, а отдельно под эту задачу ставить - нет желания
21 dkonakov
 
22.05.13
13:37
(20) Вобще странно конечно, тема то актуальная, а решения по прежнему нет.
22 dkonakov
 
25.05.13
11:12
Нашел выход: изначально файл по всем номенклатуре 4500 из них 3500 картинок весил 800 мегобайт. Удалось сжать его до 160. А потом используя опенофис удалось сжать его до 28 метров. Может не сильно рационально и формирования прайс листа занимает 6 минут, но работает.
23 MaxS
 
25.05.13
12:13
Все 3500 картинок уникальны? Есть ли способ отображать не картинку, а ссылку на первую уникальную картинку?

Или умеет ли Excel сам при сжатии файла находить дубли картинок и правильно их сжимать?
24 dkonakov
 
27.05.13
17:23
(23) да на самом деле это неважно, косяк в самой 1с, она формирует почему то ОГРОМНЫЙ файл из-за объекта "рисунок".