Рубрики
Uncategorized

Вызов Java на PHP для предварительного просмотра документа word

Автор оригинала: David Wong.

Реализация PHP предварительного просмотра документа word и различные ямы, возникшие в процессе реализации

В процессе проектирования программного обеспечения наша группа решила создать веб-сайт для обмена данными. Наиболее важной функцией веб-сайта, конечно же, является загрузка и скачивание файлов. Но есть важный процесс, который нужно пройти: предварительный просмотр.

Конечным результатом предварительного просмотра является длинная картинка, очень длинная картинка в формате png. Его можно примерно разделить на следующие этапы:

  1. Преобразование документов WORD в PDF
  2. В конце концов, разделение PDF-это всего лишь предварительный просмотр, а не взгляд вообще. Здесь я настроил предварительный просмотр 10 страниц.
  3. Преобразование изображений PDF в PNG по страницам
  4. Объедините все изображения PNG в одну длинную картинку

Четыре шага требуют различных инструментов:

Шаг 1: С помощью DuNiang мы решили использовать язык Java для реализации этой функции для преобразования WORD в PDF. Используйте OpenOffice с открытым исходным кодом + jodconverter для преобразования WORD.

Прежде всего, нам нужно рассмотреть, как PHP вызывает Java. К счастью, есть нечто под названием Java Bridge, которое решает эту проблему для нас. Использование Java Bridge содержит множество учебных пособий по блогам в Baidu. ( Ps: Хотя я не привык к плагиату этих блогов в Китае, у меня действительно есть хорошие блоги, и их много. );

Затем вам нужно установить OpenOffice, что очень просто, независимо от того, Windows или Linux это не сложно (установка Baidu search OpenOffice может быть выполнена напрямую); Наконец, загрузите пакет jar jodconverter и напишите программу для преобразования WORD в PDF.

Исходный код выглядит следующим образом

import java.io.File;
import java.io.IOException;

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;

public class PDFConverter {
    /**
     * Converting WORD documents to PDF
     *@ Param srcPath WORD document path
     *@ Param desPath Target PDF Save Path
     *@ Param pages conversion page number
     * @throws IOException
     */
    public void Word2Pdf(String srcPath, String desPath) throws IOException {
        // Source File Directory
        File inputFile = new File(srcPath);
        if (!inputFile.exists()) {
            System.out.println ("Source file does not exist! "";
            System.out.println(srcPath + ", " + desPath);
            return;
        }
        
        // Output File Directory
        File outputFile = new File(desPath);
        if (!outputFile.getParentFile().exists()) {
            outputFile.getParentFile().mkdirs();
        }
        // Call OpenOffice service threads
//        String command = "C:\Program Files (x86)\OpenOffice 4\program\soffice.exe -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\"";
        String command = "/opt/openoffice4/program/soffice -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard";
        Process p = Runtime.getRuntime().exec(command);
        // Connect to OpenOffice Service
        OpenOfficeConnection connection = new SocketOpenOfficeConnection(
                "127.0.0.1", 8100);
        connection.connect();
        // Converting word to PDF
        DocumentConverter converter = new OpenOfficeDocumentConverter(
                connection);
        converter.convert(inputFile, outputFile);
        // Close the connection
        connection.disconnect();
        // Closing process
        p.destroy();
        System.out.println ("Conversion completed! "";
    }
}

В программе мы создаем поток для открытия службы OpenOffice Process.getRuntime().exec(команда); Функция этого кода состоит в том, чтобы ввести командную строку в командной строке (терминал), которая является командой, с помощью которой мы запускаем службу open office. Затем подключите OpenOffice и используйте интерфейс, который он предоставляет, для преобразования WORD в PDF. (Примечание: Аннотированная команда является командой запуска в Windows. Поскольку пути установки OpenOffice в системах Windows и Linux различны, для запуска служб необходимы разные пути. Поэтому при установке OpenOffice важно обращать внимание на пути установки. )

Шаг 2: Разделите большой PDF-файл на маленький PDF-файл. Может быть, поддержки PHP недостаточно, или я очень люблю Java. Этот шаг, который я выбираю, заключается в использовании pdfbox Apache с Java.

Найдите pdfbox на официальном сайте apache ,скачайте fontbox-2.0.15.jar, pdfbox-2.0.15.jar, commons-logging-1.2.jar, эти три пакета jar, но я не нашел последний пакет jar на официальном веб-сайте apahce, который был загружен с облачного диска Baidu, доступного другим пользователям, поэтому, наконец, я загружу все пакеты jar, которые я использовал в облаке Baidu, и предоставлю постоянные ссылки для загрузки. Напишите программу после пакета;

Исходный код выглядит следующим образом

/**
 * splitting a large PDF into small pdf
 *@ Param SRC large PDF path
 *@ Param dest small PDF save path
 *@ Param pages split pages
 */
public void split(String src, String dest, int pages) {
    File srcFile = new File(src);
    if(!srcFile.exists()) {
        System. out. println ("original file does not exist");
        return;
    }
    
    // If the parent directory of the target path does not exist, create
    File destFile = new File(dest);
    if(!destFile.getParentFile().exists()) {
        destFile.getParentFile().mkdirs();
    }
    
    try {
        System. out. println ("start splitting");
        // Load the original PDF file
        PDDocument pdf = PDDocument.load(srcFile, MemoryUsageSetting.setupTempFileOnly());
        // Get the total number of pages of the original PDF file
        int pageCount = pdf.getPages().getCount();
        
        // When the number of pages required is greater than the total number of pages, the maximum total number of pages is split.
        if(pages > pageCount) {
            pages = pageCount;
        }
        
        PDDocument newPdf = new PDDocument();
        for(int i=0;i

Шаг 3: Преобразование изображений PDF в PNG, к счастью, обеспечивает эту функциональность в pdfbox, поэтому для этого шага не требуется никаких инструментов. Вы можете писать код напрямую.

/**
 * Convert PDF to PNG picture
 *@ Param SRC original PDF path
 *@ Parent directory of param dest pictures
 */
public void Pdf2Png(String src, String dest) {
    File srcFile = new File(src);
    if(!srcFile.exists()) {
        System. out. println ("source file does not exist");
        return;
    }
    
    File destFile = new File(dest);
    if(!destFile.exists()) {
        destFile.mkdirs();
    }
    
    try {
        PDDocument doc = PDDocument.load(srcFile);
        PDFRenderer renderer = new PDFRenderer(doc);
        int pageCount = doc.getNumberOfPages();
        for(int i=0;i

Поскольку на втором и третьем этапах используются одни и те же внешние пакеты jar, я помещаю их в один и тот же проект, и вот полный проект

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

public class PDFProcess {
    /**
     * Convert PDF to PNG picture
     *@ Param SRC original PDF path
     *@ Parent directory of param dest pictures
     */
    public void Pdf2Png(String src, String dest) {
        File srcFile = new File(src);
        if(!srcFile.exists()) {
            System. out. println ("source file does not exist");
            return;
        }
        
        File destFile = new File(dest);
        if(!destFile.exists()) {
            destFile.mkdirs();
        }
        
        try {
            PDDocument doc = PDDocument.load(srcFile);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for(int i=0;i pageCount) {
                pages = pageCount;
            }
            
            PDDocument newPdf = new PDDocument();
            for(int i=0;i

Последнее слияние PNG, это требование может быть выполнено непосредственно с помощью php , но нужна библиотека расширений GD2, если расширение автономно под Windows, Linux необходимо установить само расширение.

 $width) {
                $width = $arr[$i]['size'][0];
            }
            $height += $arr[$i]['size'][1];
        }

        $merge = imagecreate($width, $height+10*count($source));
        $space = imagecreate($width, 10);

        $dst_x = 0;
        $dst_y = 0;
        for($i=0;$i

Идея состоит в том, чтобы сначала создать пустое длинное изображение, а затем поместить объединенное изображение одно за другим (используя функцию imagecopy ()), где я выполняю интервальную обработку, каждые два изображения с интервалом в 10 пикселей.

Пока, похоже, все проблемы решены. Нам просто нужно упаковать проект Java в пакет jar и поместить его в каталог EXT среды JRE, необходимой JavaBridge для выполнения всех функций.

Однако, когда я вкладываю все в проект и запускаю его, возникают всевозможные “несчастные случаи” (особенно когда разработка Windows и последующее перенос исходного кода в Linux являются наиболее серьезными проблемами). Каковы конкретные проблемы? Позвольте мне перечислить их один за другим и объяснить их в связи с моим проектом.

  • Поскольку система отличается, поэтому разделитель путей к файлам отличается, в Windows разделителем является”/”, а в Linux разделителем является”/”, поэтому, когда я конвертирую PDF в PNG, возникает эта проблема. Теперь вернитесь к исходному коду PDF в PNG, там будет такой код. Файл Файл(dest + "\" + i + ".png"); Если вы понимаете мой код, вы поймете проблему. Все хорошо работает под Windows, но имя файла и путь создания PNG-файлов изменятся под Linux. “” здесь будет рассматриваться не как разделитель пути, а как часть имени файла. На самом деле, изменить очень просто: Файловый файл(dest + File.separator + i + ".png");
  • Создание другого потока для запуска службы OpenOffice всегда приводит к исключению, что служба не может быть подключена. Согласно моей различной отладке, я обнаружил, что иногда это происходит: когда программа запускается в службу подключения, служба не открывается. Разумно, чтобы код для открытия сервиса не был написан до подключения к сервису. Я думаю, это потому, что для запуска службы создается другой поток, а основной поток не останавливается, а продолжает выполняться. Если основной поток сначала выполнит код для подключения службы, произойдет эта ошибка. Хотя это предположение, я думаю, что есть два способа решить эту проблему.

Первый-ожидание потока, которое позволяет основному потоку ждать, пока другой поток не завершит выполнение и не разбудит основной поток. Второе-сделать службу openoffice открытой в течение длительного времени без необходимости запускать службу в программе. Поскольку он находится на ранней стадии разработки, команда решает запустить службу в течение длительного времени, а затем позже перейти к стратегии ожидания потока. Затем код необходимо изменить, чтобы удалить код, который запустил службу OpenOffice, но не забудьте запустить службу вручную.

  • Если веб-сайт размещен на удаленном сервере и может быть удаленно подключен только к терминалу без графического интерфейса, службы JavaBridge и OpenOffice должны выполняться в фоновом режиме. К счастью, в Linux есть прямые команды для преобразования процессов в фоновое выполнение, что не является большой проблемой.
  • Первый вопрос и второй вопрос нужно постоянно пытаться выяснить, в чем проблема, на что тратится большая часть времени. Последний вопрос во многом связан с опытом программирования на Java. Как упоминалось ранее, нам нужно упаковать Java-проекты в пакеты jar, и нам нужно поместить в них внешние пакеты jar. Хотя eclipse не может включать внешние пакеты jar, когда он упакован (файл JAR необходим для упаковки, а не для запуска файла Jar), мы должны найти способы подключения внешних пакетов jar. Здесь я предлагаю три метода, но я опробовал только один из них.

Способ 1. Откройте упакованный пакет jar с помощью rar и скопируйте внешний пакет jar непосредственно в него. Что касается того, куда копировать, мы можем судить по пути, используемому классом, импортирующим внешний пакет jar в программу. Мы действительно не можем судить, стоит ли пробовать каталог или каталог.

Метод 2: Внешний пакет jar был распакован во множество файлов классов, и файл класса был скопирован в целевой пакет jar. Таким образом, я прошел испытание. Например, после распаковки пакета jar jodconverter есть четыре папки (com, черновики, org, META-INT), которые копируются в каталог верхнего уровня целевого пакета jar.

Метод 3: Если вы можете найти исходный код внешнего пакета jar, вы можете скопировать исходный код непосредственно в проект и упаковать его в jar вместе с проектом. Исходный код здесь ссылается на файл Java вместо файлов класса, этот подход должен быть на 100% успешным, но, как правило, трудно найти исходный код.

Подводить итоги:

  • Файл jar эквивалентен сжатому пакету, который можно открыть с помощью программного обеспечения для сжатия, такого как winrar, и в него можно добавить другие файлы.
  • Если в программировании используется путь, не используйте “” или “/” напрямую. Используйте константы, указанные в языке программирования, для представления разделителей, таких как Файл. разделитель в Java, константа DIRECTORY_SEPARATOR в php.
  • При проверке ошибок нам необходимо объединить интерфейс с базой данных для проверки. В то же время мы можем судить о местоположении ошибок по входному журналу. Функция error_log() предусмотрена в PHP для ввода журнала.

Постоянная ссылка для загрузки пакета jar: jodconverter:https://pan.baidu.com/s/1XwhiVhmlXxVvkPiiIkYi_Q Код извлечения: 1dgj pdfbox:https://pan.baidu.com/s/19bPBsoJhEv-m0l5ZLlMZbg Код извлечения: ymnt JavaBridge:https://pan.baidu.com/s/1XKdC8vSLlmOGIGYRAmSQTA Извлечение код: k3lb

Контактная информация (qqq): 1518542802 Если вы считаете, что с этим блогом что-то не так, вы можете добавить мой вопрос, чтобы спросить меня, и вы будете знать это все время.

Оригинал: “https://developpaper.com/calling-java-in-php-to-realize-preview-of-word-document/”