Jak to z Microsoftem bywa nie jest łatwo. Są dwa formaty Excela
-- stary (.xls
) oraz nowy (.xlsx
).
Pakiety Perlowe
Spreadsheet::Excel
oraz Spreadsheet::ParseXLSX
radzą sobie
nieźle, aczkolwiek oczywiście gwarancji nie ma i być nie może skoro
sam Excel czasami siebie samego nie potrafi zinterpretować.
No ale jest jeszcze trzeci format: jak plik .xlsx
jest
zabezpieczone hasłem (password
protected). I na taką okoliczność nie ma zbyt wielu narzędzi.
Można wszakże problem rozwiązać w dwóch krokach korzystając
Libreoffice, który potrafi interpretować pliki Excela i można go
uruchomić w trybie batch:
#!/bin/bash XLS="$1" TMP="${XLS%.*}.xlsx" libreoffice --headless --convert-to xlsx "$XLS" --outdir ./xlsx-temp/ perl xslx2csv.pl ./xlsx-temp/"$TMP" "$OUTFILE"
Powyższy skrypt obsłuży wszystkie rodzaje plików Excela,
zamieniając je najpierw na plik w formacie XLSX
(plik password protected
zostanie
zmieniony na prawdziwy format XLSX,
interpretowalny przez np. Spreadsheet::ParseXLSX
).
Można od razu konwertować do CSV (--convert-to csv
), ale konwersji będzie podlegać
tylko pierwszy arkusz. Jak interesuje nas na przykład drugi, to kicha...
nie da się (a przynajmniej ja nie wiem jak to osiągnąć). Inny problem
to zamiana XLSX→XLSX -- nie ma w LibreOffice możliwości
określenia nazwy pliku wynikowego, a próba:
libreoffice --headless --convert-to xlsx plik.xlsx
Kończy się błędem. Na szczęście jest obejście w postaci
opcji --outdir
. Plik wyjściowy -- o tej samej nazwie
co wejściowy -- jest
zapisywany w innym katalogu i problem rozwiązany.
Po zamianie Excela na ,,kanoniczny'' XLSX do konwersji na CSV można wykorzystać następujący skrypt Perla:
#!/usr/bin/perl # Wykorzystanie perl xslx2csv.pl plik.xslx [numer-arkusza] use Spreadsheet::ParseXLSX; use open ":encoding(utf8)"; use open IN => ":encoding(utf8)", OUT => ":utf8"; $xslxfile = $ARGV[0]; $ArkuszNo = $ARGV[1] || 1; ## domyślnie arkuszu 1 my $source_excel = new Spreadsheet::ParseXLSX; my $source_book = $source_excel->parse("$xslxfile") or die "Could not open source Excel file $xslxfile: $!"; # Zapisuje zawartość wybranego arkusza do hasza %csv my %csv = (); foreach my $sheet_number (0 .. $source_book->{SheetCount}-1) { my $sheet = $source_book->{Worksheet}[$sheet_number]; print STDERR "*** SHEET:", $sheet->{Name}, "/", $sheet_number, "\n"; if ( $ArkuszNo == $sheet_number + 1 ) { next unless defined $sheet->{MaxRow}; next unless $sheet->{MinRow} <= $sheet->{MaxRow}; next unless defined $sheet->{MaxCol}; next unless $sheet->{MinCol} <= $sheet->{MaxCol}; foreach my $row_index ($sheet->{MinRow} .. $sheet->{MaxRow}) { foreach my $col_index ($sheet->{MinCol} .. $sheet->{MaxCol}) { my $source_cell = $sheet->{Cells}[$row_index][$col_index]; if ($source_cell) { $csv{$row_index}{$col_index} = $source_cell->Value; } } } } }
Arkusz jest w haszu %csv
.
Jak go przekształcić/wydrukować itp. pozostawiam inwencji ewentualnego czytelnika.
Zmuszony ostatnio konwertować tekst na konferencję ISD z LaTeXa do MS Word korzystałem -- jak zwykle -- z programu latex2rtf, uruchamiając go następująco:
latex2rtf -C latin2 art-oss.tex
Następnie ręcznie na cudzym komputerze poprawiam
wynik konwersji we wspomnianym MSW.
Kłopot był z diagramami, oryginalnie wykonanymi w dia. Kiedyś już
konwertowałem pliki
.dia
na dobrej jakości pliki WMF/EMF
ale nie zanotowałem tego nigdzie i oczywiście teraz zapomniałem jak to
zrobiłem. Pamiętałem tylko, że 1) zamiana jakiegokolwiek ludzkiego
formatu typu SVG/EPS/PDF na WMF to sprawa beznadziejna, 2) jakoś
mi to się udało kiedyś zrobić.
W rezultacie teraz musiałem niepotrzebnie stracić trochę
czasu żeby sobie przypomnieć, że to sama dia
potrafi
wyeksportować diagram do formatu EMF.
Dokładniej dia w wersji dla MS Windows -- moja wersja pod linuksem ma coś na ten temat na stronach podręcznika ale eksport do EMF kończy się błędem.
Jak zamienić wiele plików w formacie MS Powerpoint na dokumenty PDF
przy pomocy programu OpenOffice ale z poziomu wiersza poleceń
opisał Bob DuCharme w tekście
Moving to OpenOffice:
Batch Converting Legacy Documents. W skrócie postępuje się
następująco: w OO należy przejść do okna dialogowego
Narzędzia->Makra->Zarządzaj Makrami. Następnie
utworzyć moduł, np. MyConversion
i wpisać do okienka następującą treść :
' BASIC, see: http://www.xml.com/pub/a/2006/01/11/from-microsoft-to-openoffice.html ' Based on code from http://www.oooforum.org/forum/viewtopic.phtml?t=3772 ' Save document as an Acrobat PDF file. Sub SaveAsPDF( cFile ) cURL = ConvertToURL( cFile ) ' Open the document. Just blindly assume that the document ' is of a type that OOo will correctly recognize and open ' without specifying an import filter. oDoc = StarDesktop.loadComponentFromURL( cURL, "_blank", 0, _ Array(MakePropertyValue( "Hidden", True ),)) cFile = Left( cFile, Len( cFile ) - 4 ) + ".pdf" cURL = ConvertToURL( cFile ) ' Save the document using a filter. oDoc.storeToURL( cURL, Array(_ MakePropertyValue( "FilterName", "writer_pdf_Export" ),) oDoc.close( True ) End Sub ' Save document as a Microsoft Word file. Sub SaveAsDoc( cFile ) ' mostly a copy of SaveAsPDF cURL = ConvertToURL( cFile ) oDoc = StarDesktop.loadComponentFromURL( cURL, "_blank", 0, (_ Array(MakePropertyValue( "Hidden", True ),)) cFile = Left( cFile, Len( cFile ) - 4 ) + ".doc" cURL = ConvertToURL( cFile ) oDoc.storeToURL( cURL, Array(_ MakePropertyValue( "FilterName", "MS WinWord 6.0" ),) oDoc.close( True ) End Sub ' Save document as an OpenOffice 2 file. Sub SaveAsOOO( cFile ) ' mostly a copy of SaveAsPDF. Save as an OpenOffice file. cURL = ConvertToURL( cFile ) oDoc = StarDesktop.loadComponentFromURL( cURL, "_blank", 0, _ Array(MakePropertyValue( "Hidden", True ),)) ' Set output file extension based on lower-case ' version of input extension. Select Case LCase(Right(cFile,3)) Case "ppt" ' PowerPoint file. cFileExt = "odp" Case "doc" ' Word file. cFileExt = "odt" Case "xls" ' Excel file. cFileExt = "ods" Case Else cFileExt = "xxx" End Select cFile = Left( cFile, Len( cFile ) - 3 ) + cFileExt cURL = ConvertToURL( cFile ) oDoc.storeAsURL( cURL, Array() ) oDoc.close( True ) End Sub Function MakePropertyValue( Optional cName As String, Optional uValue ) _ As com.sun.star.beans.PropertyValue Dim oPropertyValue As New com.sun.star.beans.PropertyValue If Not IsMissing( cName ) Then oPropertyValue.Name = cName EndIf If Not IsMissing( uValue ) Then oPropertyValue.Value = uValue EndIf MakePropertyValue() = oPropertyValue End Function
Uruchamia się to następująco (Linux):
ooffice -invisible "macro:///Standard.MyConversion.SaveAsPDF($PWD/plik.ppt)"
albo via prosty jednoargumentowy skrypt oo2pdf
:
#!/bin/bash # Konwersja do formatu PDF echo "Konwertuję $1..." ooffice -invisible "macro:///Standard.MyConversion.SaveAsPDF($PWD/$1)"
Koniecznie trzeba podać pełną ścieżkę
do pliku (stąd zmienna PWD
) bo inaczej zgłoszony zostanie błąd.
W MS Windows też trzeba podać pełną nazwę, co nie do końca może być
wygodne. Ale to już nie moje zmartwienie. Makra działają nie tylko
dla plików .ppt
,
ale też .doc
i .odt/odp
.
Na ww. stronie jest też podana następująca zgrabna pętla zamieniająca wszystkie pliki (w tym przypadku .ppt) w katalogu bieżącym i jego podkatalogach:
for i in $(find ./ -name "*.ppt"); do oo2pdf $i ; done
Być może to find ./ -name
jest nawet przesadne i wystarczy
zwykłe for i in *.ppt; do
.
Jakiś czas temu
Elka
uaktualniła fragment swojej
książki
nt. akordeonów.
Ma on być wydany w postaci artykułu w wydawnictwie prestiżowej Akademii
Muzycznej. Oczywiście podesłanie tego w formacie .tex
nie wchodziło w grę. Dokument nie jest specjalnie skomplikowany, ale
zwiera kilkadziesiąt przypisów, kilkanaście rysunków i setki poleceń
służących do tworzenia skorowidzów.
W oryginale był to dokument plain TeXa,
tyle, że łatwo (na szczęście) go było zamienić na dokument LaTeXowy:
%& --translate-file=il2-pl \documentclass{article} \usepackage{polski} \usepackage{graphicx} \newcommand\PICDIR{} % \renewcommand\index[1]{} %% eat \newcommand\xindex[1]{} % \newcommand\AWindex[2][NIL]{} % \newcommand\Piece[2][NIL]{\emph{#2}} % eat \renewcommand{\includegraphics}[2][NIL]{% \begin{center}\texttt{#2.eps}\end{center}} \renewcommand\dywiz{-} \setcounter{secnumdepth}{-1} \title{Polska literatura akordeonowa...
Polecenia indeksujące \index
, \xindex
,
\AWindex
oraz \Piece
zostały przedefiniowane:
zjadają swoje argumenty i nie wstawiają nic do składu. Przedefiniowałem
też \includegraphics
, bo plik .rtf
ze wstawionymi
rysunkami miał ponad 40 Mb. Skoro ostateczny skład ma być w InDesign,
to rysunki można wysłać osobno i w lepszym formacie.
BTW: konstrukcja \newcommand\polecenie[2][NIL]
przedefiniowuje polecenie, które ma dwa argumenty, w tym
jeden (pierwszy) jest opcjonalny,
tzn. użycie takiego polecenia ma postać: \qq[pierwszy]{drugi}
albo \qq{drugi}
.
Napis NIL
,
to domyślna wartość, tego (opcjonalnego) argumentu.
Kiedy mam potrzebę zamiany pliku LaTeXa na MS Word używam latex2rtf. Nie jest to program idealny, ale lepszego nie znam:
latex2rtf -i polish -C latin2 akordeony.ltx
Przełącznik -i polish
powinien wstawiać generowane
napisy w języku polskim (tj, Rysunek zamiast Figure
itp.).
Kłopot, bo tego nie robi (wersja 1.9.16a, beta).
Próbowałem na różne sposoby a rzecz wydaje się banalna, jednak
uparcie wstawiane są teksty angielskie (można to ew. poprawić edytując
plik RTF, np. Perlem).
Za to przełącznik -C
, ustawiający stronę kodową, działa.
Po uruchomieniu latex2rtf, pojawiło się kilka ostrzeżeń:
akordeony.ltx:3 Unknown style option polski ignored akordeony.ltx:4 Unknown style option graphicx ignored akordeony.ltx:9 No existing definition for \index akordeony.ltx:13 No existing definition for \includegraphics akordeony.ltx:14 No existing definition for \dywiz
Ale konwersja została dokonana (prawie) prawidłowo.
W szczególności
latex2rtf prawidłowo zinterpretował moje redefinicje i pominął
zwartość poleceń indeksujących a zamiast plików graficznych wstawił
ich nazwy.
Jedyny błąd jaki zauważyłem, to wstawianie zbędnego
odstępu pomiędzy \footnote
a następującym po numerze
przypisu znakiem przestankowym, tj. numer-odstęp-kropka, zamiast
numer-kropka.
Przy okazji konwersji z LaTeXa do MSW: dia potrafi wyeksportować dobrej jakości diagramy w formacie EMF.