2013-02-27 38 views
9

Tôi đang chuyển đổi hàng trăm tệp ODT thành tệp PDF và mất một thời gian dài để thực hiện việc này. Tôi có một CPU với nhiều lõi. Có thể sử dụng bash hoặc python để viết một kịch bản để làm điều này song song? Có cách nào để song song (không chắc chắn nếu tôi đang sử dụng đúng từ) chuyển đổi tài liệu theo lô bằng cách sử dụng libreoffice từ dòng lệnh không? Tôi đã được làm việc đó trong python/bash gọi các lệnh sau:Chuyển đổi tài liệu song song ODT> PDF Libreoffice

libreoffice --headless --convert-to pdf *appsmergeme.odt 

HOẶC

subprocess.call(str('cd $HOME; libreoffice --headless --convert-to pdf *appsmergeme.odt'), shell=True); 

Cảm ơn bạn!

Tim

+0

Bạn có ý định chạy một lệnh 'libreoffice' duy nhất trên nhiều CPU hoặc thực hiện nhiều cuộc gọi đến' libreoffice' và chuyển đổi các tệp riêng biệt không? Trong trường hợp đầu tiên bạn không thể làm bất cứ điều gì, trong trường hợp thứ hai nó là đơn giản. – Bakuriu

+2

Uhm, tôi tin rằng 'libreoffice' ngăn bạn chạy nhiều hơn một trình chuyển đổi pdf đồng thời. Cố gắng tạo nhiều quy trình chỉ tạo ra một tệp '.pdf' duy nhất và các quy trình khác không thành công. Điều này xảy ra ngay cả khi sử dụng tùy chọn '--nolockcheck'. Vì vậy, tôi tin rằng câu trả lời cho câu hỏi của bạn là: bạn không thể. Bạn nên sử dụng một chương trình khác để chuyển đổi. – Bakuriu

+0

Tôi tin rằng tôi đã từng đọc rằng libreoffice luôn luôn chỉ sử dụng một quy trình (cũng qua nhà văn, gây ấn tượng, vv), điều đó có thể khiến điều này có thể là không thể. – lolopop

Trả lời

3

Bạn có thể chạy libreoffice làm daemon/dịch vụ. Vui lòng kiểm tra liên kết sau, có thể nó cũng giúp bạn: Daemonize the LibreOffice service

Khả năng khác là sử dụng unoconv. "unoconv là một tiện ích dòng lệnh có thể chuyển đổi bất kỳ định dạng tệp nào mà OpenOffice có thể nhập, thành bất kỳ định dạng tệp nào mà OpenOffice có khả năng xuất."

-1

chưa được kiểm tra khả năng hợp lệ:

Bạn/có thể/có thể:

  • Divide lên các tập tin vào một số lô song song trong một số cách công bằng, ví dụ đặt tất cả chúng vào các thư mục;
  • Tạo tài khoản người dùng cục bộ riêng biệt để xử lý từng thư mục;
  • Chạy Libreoffice serially như mỗi người dùng

ví dụ:

for paralleluser in timlev1 timlev2 timlev3 timlev4 ; do 
     su - $paralleluser -c \ 
     "for file in /var/spool/pdfbatches/$paralleluser ; do \ 
      libreoffice --headless --convert-to pdf $file ; done" 
done 

Bằng cách sử dụng su - bạn sẽ không vô tình thừa hưởng bất kỳ biến môi trường từ phiên thực sự của bạn, do đó quá trình song song không nên can thiệp với nhau (ngoài cạnh tranh cho các nguồn lực).

Xin lưu ý, đây có thể là nhiệm vụ I/O-ràng buộc, do đó, chạy 1 trên mỗi lõi CPU có thể sẽ là không phải tăng tốc cho bạn rất nhiều.

+0

Mở/Libreoffice không cho phép chạy soffice.exe song song – luca76

0

chủ đề hoặc câu trả lời này cũ. Tôi đã thử nghiệm libreoffice 4.4, tôi có thể xác nhận rằng tôi có thể chạy đồng thời libreoffice. xem tập lệnh của tôi.

for odt in test*odt ; do 
 
echo $odt 
 
soffice --headless --convert-to pdf $odt & 
 
ps -ef|grep ffice 
 
done

0

Tôi đã viết một chương trình trong golang để chuyển đổi hàng loạt hàng ngàn file doc/xls.

  • xác định "gốc" giá trị biến đến đường dẫn của tài liệu của bạn để chuyển đổi
  • đã chuyển đổi tài liệu pdf được bỏ qua (nếu không muốn nói, bình luận các điều kiện kiểm tra trong chuyến thăm function())
  • đây Tôi đang sử dụng 4 chủ đề (Tôi có một i3 Intel với 4 lõi). Bạn có thể sửa đổi giá trị trong hàm main()

Đôi khi có thể xảy ra Libreoffice không chuyển đổi một số tệp, vì vậy bạn nên mở và chuyển đổi chúng thành PDF theo cách thủ công. May mắn thay, họ chỉ có 10 trong số 16.000 tài liệu của tôi để chuyển đổi.

package main 

import (
    "os/exec" 
    "sync" 
    "path/filepath" 
    "os" 
    "fmt" 
    "strings" 
) 

// root dir of your documents to convert 
root := "/.../conversion-from-office/" 

var tasks = make(chan *exec.Cmd, 64) 

func visit(path string, f os.FileInfo, err error) error { 
    if (f.IsDir()) { 
     // fmt.Printf("Entering %s\n", path) 
    } else { 
     ext := filepath.Ext(path) 
     if (strings.ToLower (ext) == "pdf") { 
     } else { 


      outfile := path[0:len(path)-len(ext)] + ".pdf" 

      if _, err := os.Stat(outfile); os.IsNotExist(err) { 

       fmt.Printf("Converting %s\n", path) 

       outdir := filepath.Dir(path) 
       tasks <- exec.Command("soffice", "--headless", "--convert-to", "pdf", path, "--outdir", outdir) 
      } 
     } 
    } 
    return nil 
} 


func main() { 
    // spawn four worker goroutines 
    var wg sync.WaitGroup 

    // the ...; i < 4;... indicates that I'm using 4 threads 
    for i := 0; i < 4; i++ { 
     wg.Add(1) 
     go func() { 
      for cmd := range tasks { 
       cmd.Run() 
      } 
      wg.Done() 
     }() 
    } 


    err := filepath.Walk(root, visit) 
    fmt.Printf("filepath.Walk() returned %v\n", err) 

    close(tasks) 

    // wait for the workers to finish 
    wg.Wait() 
} 
0

Chúng tôi gặp sự cố tương tự với unoconv. unoconv nội bộ sử dụng số libreoffice. Chúng tôi đã giải quyết nó bằng cách gửi nhiều tệp đến unoconv trong một lần gọi. Vì vậy, thay vì lặp qua tất cả các tệp, chúng tôi chỉ phân vùng tập hợp các tệp thành các nhóm, mỗi nhóm đại diện cho định dạng o/p. Sau đó, chúng tôi thực hiện càng nhiều cuộc gọi càng nhiều càng tốt.

Tôi khá chắc chắn libreoffice cũng có chế độ tương tự.

0

Kể từ khi tác giả đã giới thiệu Python như một câu trả lời hợp lệ:

import subprocess 
import os, glob 
from multiprocessing.dummy import Pool # wrapper around the threading module 

def worker(fname, dstdir=os.path.expanduser("~")): 
    subprocess.call(["libreoffice", "--headless", "--convert-to", "pdf", fname], 
        cwd=dstdir) 

pool = Pool() 
pool.map(worker, glob.iglob(
     os.path.join(os.path.expanduser("~"), "*appsmergeme.odt") 
    )) 

Sử dụng một hồ bơi thread thay vì một hồ bơi quá trình multiprocessing.dummy là đủ vì quy trình mới cho xử lý song song thực đang đẻ trứng bằng subprocess.call() anyway.

Chúng tôi có thể đặt lệnh cũng như thư mục hoạt động hiện tại cwd trực tiếp. Không cần phải tải shell cho mỗi tệp để thực hiện điều đó. Hơn nữa, os.path cho phép khả năng tương tác đa nền tảng.

Các vấn đề liên quan