Форматированный текст Ueditor повторяет документы Word (поддерживаются форматы doc и docx) для вторичного редактирования, серверная часть Springboot
Форматированный текст Ueditor повторяет документы Word (поддерживаются форматы doc и docx) для вторичного редактирования, серверная часть Springboot

Совет: После написания статьи оглавление может быть сгенерировано автоматически. О том, как его создать, см. в справочном документе справа.

vue+ueditor+springboot, реализовать загрузку и редактирование документов Word


Предисловие

`Внешний интерфейс импортирует документы Word (поддерживаются форматы doc и docx), а форматированный текст Ueditor отображается для вторичного редактирования. В настоящее время проект ueditor заархивирован, и соответствующие материалы для реализации этих двух форматов относительно скудны.

`Решение:

1. Загрузите текстовый файл

2. Чтение и создание HTML-файлов в фоновом режиме.

3. Прочитайте содержимое html-файла в фоновом режиме и верните его во внешний интерфейс.

Подарите кому-нибудь розу, оставьте в руке стойкий аромат.

1. Цель

При загрузке файла Word он анализируется и передается во внешний интерфейс через фон.

2. Этапы кода

Структура внутреннего кода:

1. библиотека зависимостей Maven

Язык кода:c
копировать
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.15</version>
        </dependency>

        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
            <version>1.0.6</version>
        </dependency>

2. Страница vue считывает конфигурацию ueditor.

Код выглядит следующим образом:

Язык кода:c
копировать
 /**
     *  Получить конфигурацию загрузки файла UE
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping(value = "/config")
    public void ueConfig(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        String urlPrefix = ueProperties.getSavepath();
        log.info("urlPrefix = "+urlPrefix);
        String exec = "{\n" +
                "    /* Загрузить элементы конфигурации изображения */\n" +
                "    \"imageActionName\": \"catcherImage\", /* Название действия, которое выполняет загруженное изображение */\n" +
                "    \"imageFieldName\": \"upfile\", /* Название формы отправленного изображения */\n" +
                "    \"imageMaxSize\": 2048, /* Ограничение размера загрузки, единица Б */\n" +
                "    \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* Загрузить изображение в формате отображения */\n" +
                "    \"imageCompressEnable\": true, /* Сжимать ли изображения, по умолчанию установлено значение true. */\n" +
                "    \"imageCompressBorder\": 800, /* Предел сжатия изображения по длинной стороне */\n" +
                "    \"imageInsertAlign\": \"none\", /* Метод вставленного плавающего изображения */\n" +
                "    \"imageUrlPrefix\": \"" + urlPrefix + "\", /* Префикс пути доступа к изображению */\n" +
                "    \"imagePathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* Загрузите путь сохранения, вы можете настроить путь сохранения и формат имени файла. */\n" +
                "                                /* {filename} Оно будет заменено исходным именем файла. При настройке необходимо обратить внимание на проблему искажения китайских символов. */\n" +
                "                                /* {rand:6} будет заменено случайным числом, а следующее число — это количество цифр в случайном числе. */\n" +
                "                                /* {time} будет заменен временной меткой */\n" +
                "                                /* {yyyy} будет заменен четырехзначным годом */\n" +
                "                                /* {yy} будет заменен двузначным годом */\n" +
                "                                /* {mm} будет заменено двумя цифрами месяца */\n" +
                "                                /* {dd} будет заменено двузначной датой */\n" +
                "                                /* {hh} будет заменено на два часа */\n" +
                "                                /* {ii} будут заменены двузначными минутами */\n" +
                "                                /* {ss} будет заменено двузначными секундами */\n" +
                "                                /* Недопустимые символы \\ : * ? \" < > | */\n" +
                "                                /* Подробности смотрите в онлайн-документации: fex.baidu.com/ueditor/#use-format_upload_filename */\n" +
                "\n" +
                "    /* Элементы конфигурации загрузки изображений Tuya */\n" +
                "    \"scrawlActionName\": \"uploadscrawl\", /* Имя действия для выполнения загрузки граффити. */\n" +
                "    \"scrawlFieldName\": \"upfile\", /* Название формы отправленного изображения */\n" +
                "    \"scrawlPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* Загрузите путь сохранения, вы можете настроить путь сохранения и формат имени файла. */\n" +
                "    \"scrawlMaxSize\": 2048000, /* Ограничение размера загрузки, единица Б */\n" +
                "    \"scrawlUrlPrefix\": \"\", /* Префикс пути доступа к изображению */\n" +
                "    \"scrawlInsertAlign\": \"none\",\n" +
                "\n" +
                "    /* Загрузка инструмента для создания снимков экрана */\n" +
                "    \"snapscreenActionName\": \"uploadimage\", /* Название действия, выполняющего загрузку скриншотов */\n" +
                "    \"snapscreenPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* Загрузите путь сохранения, вы можете настроить путь сохранения и формат имени файла. */\n" +
                "    \"snapscreenUrlPrefix\": \"\", /* Префикс пути доступа к изображению */\n" +
                "    \"snapscreenInsertAlign\": \"none\", /* Метод вставленного плавающего изображения */\n" +
                "\n" +
                "    /* Захват конфигурации удаленного образа */\n" +
                "    \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n" +
                "    \"catcherActionName\": \"catchimage\", /* Название действия, используемого для захвата удаленных изображений */\n" +
                "    \"catcherFieldName\": \"source\", /* Название формы списка отправленных изображений */\n" +
                "    \"catcherPathFormat\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* Загрузите путь сохранения, вы можете настроить путь сохранения и формат имени файла. */\n" +
                "    \"catcherUrlPrefix\": \"" + urlPrefix + "\", /* Префикс пути доступа к изображению */\n" +
                "    \"catcherMaxSize\": 2048000, /* Ограничение размера загрузки, единица Б */\n" +
                "    \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* Отображение формата захвата изображения */\n" +
                "\n" +
                "    /* Загрузить конфигурацию видео */\n" +
                "    \"videoActionName\": \"uploadvideo\", /* Имя действия для выполнения загруженного видео. */\n" +
                "    \"videoFieldName\": \"upfile\", /* Название формы отправленного видео */\n" +
                "    \"videoPathFormat\": \"/ueditor/video/{yyyy}{mm}{dd}/\", /* Загрузите путь сохранения, вы можете настроить путь сохранения и формат имени файла. */\n" +
                "    \"videoUrlPrefix\": \"\", /* Префикс пути доступа к видео */\n" +
                "    \"videoMaxSize\": 10240000, /* Ограничение размера загрузки, единица Б,По умолчанию10 МБ */\n" +
                "    \"videoAllowFiles\": [\n" +
                "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
                "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\"], /* Загрузить видео в формате отображения */\n" +
                "    /* Загрузить файл конфигурации */\n" +
                "    \"fileActionName\": \"uploadfile\",/* В контроллере,Имя действия для выполнения загруженного видео. */\n" +
                "    \"fileFieldName\": \"upfile\", /* Имя отправленной формы файла */\n" +
                "    \"filePathFormat\": \"/ueditor/file/{yyyy}{mm}{dd}/\", /* Загрузите путь сохранения, вы можете настроить путь сохранения и формат имени файла. */\n" +
                "    \"fileUrlPrefix\": \"\", /* Префикс пути доступа к файлу */\n" +
                "    \"fileMaxSize\": 10240000, /* Ограничение размера загрузки, единица Б,По умолчанию10 МБ */\n" +
                "    \"fileAllowFiles\": [\n" +
                "        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
                "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
                "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
                "        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
                "        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
                "    ], /* Отображение формата загрузки файла */\n" +
                "    /* Список изображений в указанном каталоге */\n" +
                "    \"imageManagerActionName\": \"listimage\", /* Имя действия для управления изображениями */\n" +
                "    \"imageManagerListPath\": \"/ueditor/image/{yyyy}{mm}{dd}/\", /* Укажите каталог, в котором будут перечислены изображения. */\n" +
                "    \"imageManagerListSize\": 20, /* Количество файлов, отображаемых каждый раз */\n" +
                "    \"imageManagerUrlPrefix\": \"" + urlPrefix + "\", /* Префикс пути доступа к изображению */\n" +
                "    \"imageManagerInsertAlign\": \"none\", /* Метод вставленного плавающего изображения */\n" +
                "    \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* Перечисленные типы файлов */\n" +
                "    /* Список файлов в указанном каталоге */\n" +
                "    \"fileManagerActionName\": \"listfile\", /* Имя действия для управления файлами */\n" +
                "    \"fileManagerListPath\": \"/ueditor/file/{yyyy}{mm}{dd}/\", /* Укажите каталог, в котором должны быть перечислены файлы */\n" +
                "    \"fileManagerUrlPrefix\": \"\", /* Префикс пути доступа к файлу */\n" +
                "    \"fileManagerListSize\": 20, /* Количество файлов, отображаемых каждый раз */\n" +
                "    \"fileManagerAllowFiles\": [\n" +
                "        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
                "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
                "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
                "        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
                "        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
                "    ] /* Перечисленные типы файлов */\n" +
                "}";
        PrintWriter writer = response.getWriter();
        writer.write(exec);
        writer.flush();
        writer.close();
    }

3. Файл импорта внешнего интерфейса.

Код выглядит следующим образом:

Язык кода:c
копировать
 methods: {
        ready(editorInstance) {
          this.editorInstance=editorInstance
          async uploadWordFile(event) {
              const file = event.target.files[0];
              if (!file) return;
              // Преобразование файлов Word в HTML
              const htmlContent = await this.convertWordToHtml(file);
               const jsonData = JSON.parse(htmlContent)
               // Установите содержимое UEditor
               console.log(jsonData)
               this.editorInstance.execCommand('inserthtml',jsonData.data)
          },
          async convertWordToHtml(wordFile) {
            // Это должен быть код вызова внутреннего интерфейса для преобразования файлов Word в HTML.
            // Предположим, есть серверный API, который преобразует Word в HTML.
            const formData = new FormData();
            formData.append('file', wordFile); 
            const response = await fetch('/api/ue/uploadFile',{
              method:'POST',
              body:formData
            })
            if (response.ok) {
              return await response.text();
            }
            throw new Ошибка('Конвертация не удалась');
          }
      },

4. Серверная часть читает файл и генерирует HTML.

Код выглядит следующим образом:

Язык кода:c
копировать
/** загрузка документа word
     *
     * @param file
     * @return
     */
    @PostMapping("/uploadFile")
    public Object uploadFile(@RequestParam(name = "file") MultipartFile file){
        String filename = file.getOriginalFilename();
        JSONObject result = new JSONObject();
        String visitHtml = "";
        try {
            if (filename.endsWith(".docx")) {
                //TODO Обработка формата docx
                visitHtml = WordConverHtmlUtils.docxToHtmlText(file, ueProperties);
            } else if (filename.endsWith(".doc")) {
                //TODO Обработка формата документа
                visitHtml = WordConverHtmlUtils.docToHtmlText(file, ueProperties);
            } else {
                log.error("Неподдерживаемый формат файла!");
            }
            result.put("state", "SUCCESS");
            result.put("data", visitHtml);
            log.info("result: {}", result.toString());
        } catch (Exception e) {
            log.error("Исключение: файл не найден!");
            e.printStackTrace();
        }
        return result;
    }

5. Класс инструмента WordConverHtmlUtils.

**⚠️⚠️⚠️⚠️⚠️

options.URIResolver(new BasicURIResolver(picUri));

Необходимо установить адрес изображения, к которому внешний интерфейс может получить прямой доступ, например, автора: http://localhost:8000/resource/ueditor/file/20240404/1712220732312.png,

⚠️⚠️⚠️⚠️⚠️ В противном случае редактор ueditor не сможет отобразить картинки в документе Word**

Код выглядит следующим образом:

Язык кода:c
копировать
package com.ue.demo.utils;

import cn.hutool.core.lang.UUID;
import com.ue.demo.config.UeProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.xwpf.converter.core.BasicURIResolver;
import org.apache.poi.xwpf.converter.core.FileImageExtractor;
import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @author:Peanut
 * @create: 2024-04-05 10:22
 * @version: 1.0.0
 * @description:
 */
@Slf4j
public class WordConverHtmlUtils {
    private final static String FILE_URL_PRE = "/ueditor/file/";
    /**
     * Загрузите документ docx и верните проанализированный Html.
     */
    public static String docxToHtmlText(MultipartFile file, UeProperties ueProperties) throws Exception {
        try {
            String fileName = UUID.fastUUID().toString();
            //адрес хранения изображений
            String imagePath = ueProperties.getSavepath().concat(FILE_URL_PRE).concat("/");
            String fileOutName = imagePath.concat(fileName).concat(".html");
            log.info("Загрузить анализ документа docx");
            log.info("Загрузите документ docx и верните проанализированный Html., imagePath:{}", imagePath);
            log.info("fileOutName:{}", fileOutName);
            //Получаем объект, используемый для работы с Word
            XWPFDocument document = new XWPFDocument(file.getInputStream());
            //Некоторые основные классы настроек при экспорте в html
            XHTMLOptions options = null;
            //Определяем, есть ли картинки в вордовом файле
            if(document.getAllPictures().size() > 0) {
                //Получаем объект по умолчанию и устанавливаем отступ
                options = XHTMLOptions.getDefault().indent(4);
                // Если изображения включены, установите местоположение экспорта изображений.
                File imageFolder = new File(imagePath);
                //Установим папку назначения для экстрактора изображений Используется для хранения файлов изображений
                options.setExtractor(new FileImageExtractor(imageFolder));
                // URI resolver  Путь к каталогу изображений в HTML HTML
                //⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
                //⚠️⚠️⚠️⚠️⚠️ Необходимо установить адрес изображения, к которому внешний интерфейс может получить прямой доступ, например, автора: http://localhost:8000/resource/ueditor/file/20240404/1712220732312.png,
                //⚠️⚠️⚠️⚠️⚠️ В противном случае редактор ueditor не сможет отобразить картинки в документе Word.
                String picUri = ueProperties.getShowpath().concat(imagePath.substring(imagePath.indexOf("ueditor")));
                options.URIResolver(new BasicURIResolver(picUri));
            }

            //Получаем выходной объект HTML-файла
            File outFile = new File(fileOutName);
            if(!outFile.getParentFile().exists()){
                outFile.getParentFile().mkdirs();
            }
            //Создаем все родительские пути, если родительский каталог не существует
            outFile.getParentFile().mkdirs();
            //Создаем выходной поток
            OutputStream out = new FileOutputStream(outFile);
            //html-конвертер
            XHTMLConverter.getInstance().convert(document, out, options);
            log.info("HTML-конвертер success");
            //Обрабатываем сгенерированный HTML-код и передаем его интерфейсу в виде строки
            return readHtmlStr(fileOutName);
        } catch (Exception e) {
            log.error("docxToHtmlText Исключение синтаксического анализа", e);
        }
        return "";
    }

    /**
     * Загрузите документ Word в формате doc и верните проанализированный Html.
     * @param file
     * @param ueProperties
     * @return
     * @throws Exception
     */
    public static String docToHtmlText(MultipartFile file, UeProperties ueProperties) throws Exception {
        //Используем поток массива символов для получения проанализированного содержимого
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        OutputStream outStream = new BufferedOutputStream(baos);
        try {
            String fileName = UUID.fastUUID().toString();
            //Передаем загруженный файл в преобразование документов
            //адрес хранения изображений
            String docPath = ueProperties.getSavepath().concat(FILE_URL_PRE).concat("/");
            String imagePath = docPath.concat("image/");
            String fileOutName = docPath.concat(fileName).concat(".html");
            log.info("Загрузить документ, вернуть анализ ");
            log.info("fileOutName:{}", fileOutName);
            //Создаем каталог для хранения файлов изображений
            new File(imagePath).mkdirs();
            //Класс сущности, соответствующий документу в poi
            HWPFDocument hwpfDocument = new HWPFDocument(file.getInputStream());
            //Создаем объект преобразования, используя пустой объект документа
            WordToHtmlConverter converter = new WordToHtmlConverter(DocumentBuilderFactory
                    .newInstance()
                    .newDocumentBuilder()
                    .newDocument());

            //Устанавливаем менеджер для хранения картинок, реализованный с использованием анонимных внутренних классов Этот класс реализует интерфейс PicturesManager и метод savePicture.
            converter.setPicturesManager(new PicturesManager() {
                FileOutputStream out = null;
                //Этот метод будет вызываться внутри метода ProcessDocument ниже Используется для хранения файлов изображений в Word.
                @Override
                public String savePicture(byte[] bytes, PictureType pictureType, String name, float width, float height) {
                    try {
                        //Сохраняем одну фотографию
                        out = new FileOutputStream(imagePath + name);
                        out.write(bytes);
                    } catch (IOException exception) {
                        exception.printStackTrace();
                    }finally {
                        if(out != null) {
                            try {
                                out.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    //Здесь нам нужно вернуть сохраненный путь оператору (HtmlDocumentFacade) Используется для поиска ресурсов изображения при создании Html.
                    //⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
                    //⚠️⚠️⚠️⚠️⚠️ Необходимо установить адрес изображения, к которому внешний интерфейс может получить прямой доступ, например, автора: http://localhost:8000/resource/ueditor/file/20240404/1712220732312.png,
                    //⚠️⚠️⚠️⚠️⚠️ В противном случае редактор ueditor не сможет отобразить картинки в документе Word.
                    return ueProperties.getShowpath().concat(imagePath.substring(imagePath.indexOf("ueditor"))).concat(name);
                }
            });
            //Используем режим внешнего вида, чтобы установить для объекта документа hwpfDocument свойство Document в HtmlDocumentFacade
            converter.processDocument(hwpfDocument);
            //Получаем документ document в конвертере
            Document htmlDocument = converter.getDocument();
            //Действует как объектная модель документа (DOM) Владелец преобразованного исходного дерева в форме дерева.  -- исходное дерево
            DOMSource domSource = new DOMSource(htmlDocument);

            //конвертер Этот объект используется для конвертации исходного дерево Преобразовать в дерево результатов
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            //Установим метод вывода, который также можно назвать типом файла результирующего дерева. Это может быть html/xml/text или какой-либо тип расширения, расширяющий первые три.
            transformer.setOutputProperty(OutputKeys.METHOD , "html");
            //Установим некоторые необходимые атрибуты Установите кодировку при выводе в utf-8.
            transformer.setOutputProperty(OutputKeys.ENCODING , "utf-8");

            //Конвертировать Введите исходное дерево Преобразовать в дерево результатови вывести вstreamResultсередина
            transformer.transform(domSource , new StreamResult(new File(fileOutName)));
            log.info("HTML-конвертер success");
            //Обрабатываем сгенерированный HTML-код и передаем его интерфейсу в виде строки
            return readHtmlStr(fileOutName);
        } catch (Exception e) {
            log.error("docToHtmlText аномальный", e);
        } finally {
            baos.close();
            outStream.close();
        }
        return null;
    }

    /**
     * Прочтите html-файл, преобразуйте его в строку и верните во внешний интерфейс.
     * Удалить разрывы строк и два последовательных пробела
     * @param htmlDirPath путь к html-файлу
     * @return
     * @throws IOException
     */
    private static String readHtmlStr(String htmlDirPath) throws IOException {
        log.info("Обработайте сгенерированный HTML-код и передайте его интерфейсу в виде строки: {} ...Start..", htmlDirPath);
        String htmlStr = "";
        try {
            Path htmlPath = Paths.get(htmlDirPath);
            htmlStr = new String(Files.readAllBytes(htmlPath));
            htmlStr = htmlStr.replaceAll("\\n", "");
            htmlStr = htmlStr.replaceAll("\\s{2,}", " ");
            log.info("Обработать сгенерированный HTML-код и передать его интерфейсу в виде строки...end");
        } catch (IOException e) {
            log.error("При обработке сгенерированного HTML-кода в строковой форме произошла ошибка, {}", e.getMessage());
        }
        return htmlStr;
    }
}

6. Файл конфигурации серверной части

Код выглядит следующим образом:

Язык кода:c
копировать
spring.application.name=ue
server.port=8000

##Конфигурация редактора UE
#Editor обращается к адресу изображения сервера
ue.showpath=http://localhost:8000/resource
#ue префикс пути к хранилищу файлов
ue.savepath=/Users/cookie/Documents/coding/uedemo

!!!ue.showpath=Если у вас работает nginx, вам необходимо настроить его в nginx.conf

3. Ощутите эффект

Подвести итог

Подарите кому-нибудь розу, оставьте в руке стойкий аромат.

Адрес исходного кода:

https://gitee.com/gwancookie/uedemo

Прочтите текстовый документ, чтобы создать ссылку в формате HTML:

https://blog.csdn.net/qq_44717657/article/details/124497326

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода