原文:勿意、勿必、勿固、勿我。
译文:不凭空臆测,不武断绝对,不固执拘泥,不自以为是。
一、准备工作
1、下载地址:LibreOffice 官网
2、centos系统:作者使用7+版本
二、安装LibreOffice
下载好的安装包,选择系统匹配的安装包
选择你对应操作系统的包,我这里是Linux的rpm包,建议选择稳定版本
官网安装指南:官网首页帮助与支持——>安装指南——>选择你自己系统的点击进入
上传至服务器。
centos系统根目录opt文件夹下
cd /opt
解压文字编码
tar -zxvf LibreOffice_7.5.9.2_Linux_x86-64_rpm_langpack_zh-CN.tar.gz
解压LibreOffice
tar -zxvf LibreOffice_7.5.9.2_Linux_x86-64_rpm.tar.gz
进入RPMS目录
cd LibreOffice_7.5.9.2_Linux_x86-64_rpm/RPMS/
安装LibreOffice
yum localinstall *.rpm
进入RPMS目录
cd LibreOffice_7.5.9.2_Linux_x86-64_rpm_langpack_zh-CN/RPMS/
安装字体编码
yum localinstall *.rpm
验证是否安装成功
libreoffice7.5 --version
成功
卸载LibreOffice
yum remove libreoffice*
四、报错
yum install cairo -y
yum install cups-libs -y
yum install libSM -y
更新依赖
yum install -y libreoffice-headless
服务器命令行测试生成PDF
libreoffice7.5 --headless --invisible --convert-to pdf /opt/xxx.docx --outdir /opt
转换成功!
解决转换后的PDF中的中文乱码问题
一般在windows下安装我们的LibreOffice成功后,转换中文都是正常的,但在linux上基本上都会出现乱码的问题。 因为linux中缺少一些中文字体导致的。这个时候我们需要把windos中的字体文件夹上传到linux上,同步一下字体信息。
1、打开windows下C:\Windows\fonts目录
2、将fonts目录压缩为zip包,然后上传到服务器上。上传路径为 /usr/share/fonts
3、在linux上解压上传的压缩包,因为是zip包,需要unzip命令。 如果没有要安装
yum -y install unzip
4、输入fc-list 查看系统的字体,如果报错后,需要下载,下载完成后就可以看了
yum -y install cups-libs fontconfig
5、给给解压后产生的文件夹Fonts权限
chmod -R 755 /usr/share/fonts/Fonts
6、安装ttmkfdir,然后执行对应命令
yum -y install ttmkfdir
ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
7、用vi/vim打开/etc/fonts/fonts.conf,添加我们字体文件的位置
vim /etc/fonts/fonts.conf
<dir>/usr/share/fonts/Fonts</dir>
8、刷新内存中的字体缓存,输入:
fc-cache
9、fc-list查看一下linux系统中的字体, 有我们刚刚添加进去的
fc-list
10、再试下转换,发现中文转换成功
documents4j方式集成LibreOffice
1、引入依赖
<dependency>
<groupId>com.documents4j</groupId>
<artifactId>documents4j-local</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>com.documents4j</groupId>
<artifactId>documents4j-transformer-msoffice-word</artifactId>
<version>1.0.3</version>
</dependency>
2、实现word转pdf的工具类代码,适用于window系统和Linux系统
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.jeecg.common.util.DateUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
@Slf4j
public class PdfUtil {
/**
* 通过documents4j 实现word转pdf
*/
public static String documents4jWordToPdf(HttpServletRequest request, String wordPath, String pdfDownloadPath) {
//获取系统类型
String os = System.getProperty("os.name").toLowerCase();
String ym = DateUtils.getDate("yyyyMM");
String filePath = pdfDownloadPath + "/" + ym;
File path = new File(filePath);
// 检查目录是否存在
if (!path.exists()) {
// 创建目录
boolean created = path.mkdirs();
if (created) {
log.info("目录已创建");
} else {
log.info("目录创建失败");
}
} else {
log.info("目录已经存在或文件不在有效目录中");
}
String fileName = wordPath.substring(wordPath.lastIndexOf("/") + 1, wordPath.lastIndexOf("."));
log.info("fileName:{}", fileName);
log.info("当前系统:{}", os);
if (os.contains("win")) {
String pdfPath = pdfDownloadPath + ym + "/" + fileName + ".pdf";
File wordFile = null;
if (ObjectUtils.isNotEmpty(wordPath) && wordPath.indexOf("http") == -1) {
wordFile = new File(wordPath);
} else {
wordFile = getFileByHttpURL(wordPath);
}
// Windows操作系统
winDocuments4jWordToPdf(wordFile, pdfPath);
return org.jeecg.common.util.http.HttpUtil.getServerUrl(request, 10) + "/pdf/" + ym + "/" + fileName + ".pdf";
} else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
String pdfPath = pdfDownloadPath + ym + "/";
String wordWritePath = pdfDownloadPath + ym + "/" + fileName + ".docx";
try {
if (ObjectUtils.isNotEmpty(wordPath) && wordPath.indexOf("http") == -1) {
// 创建源文件和目标文件的路径对象
Path sourcePath = Paths.get(wordPath);
Path destinationPath = Paths.get(filePath, sourcePath.getFileName().toString());
Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
} else {
InputStream inputStream = new URL(wordPath).openStream();
// 创建XWPFDocument对象
XWPFDocument document = new XWPFDocument(inputStream);
// 创建输出流,将Word文件写入到本地指定文件夹
FileOutputStream outputStream = new FileOutputStream(wordWritePath);
document.write(outputStream);
outputStream.close();
log.info("Word文件已成功保存到本地!");
}
} catch (IOException e) {
log.info("发生错误: {}" + e.getMessage());
}
File linuxWordPath = new File(wordWritePath);
// Unix/Linux/Mac操作系统
linuxDocuments4jWordToPdf(linuxWordPath, pdfPath);
return org.jeecg.common.util.http.HttpUtil.getServerUrl(request, 10) + "/pdf/" + ym + "/" + fileName + ".pdf";
} else {
// 未知操作系统
throw new RuntimeException("不支持当前操作系统转换文档");
}
}
public static String winDocuments4jWordToPdf(File wordFile, String pdfPath) {
InputStream docxInputStream = null;
OutputStream outputStream = null;
try {
// 原word地址
docxInputStream = new FileInputStream(wordFile);
// 转换后pdf生成地址
outputStream = new FileOutputStream(pdfPath);
IConverter converter = LocalConverter.builder().build();
converter.convert(docxInputStream)
.as(DocumentType.DOCX)
.to(outputStream)
.as(DocumentType.PDF).execute();
// 关闭
converter.shutDown();
// 关闭
outputStream.close();
// 关闭
docxInputStream.close();
return pdfPath;
} catch (Exception e) {
e.printStackTrace();
log.info("[documents4J] word转pdf失败:" + e.toString());
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
if (docxInputStream != null) {
docxInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
log.info("[documents4J] word转pdf失败:" + e.toString());
}
}
return "";
}
/**
* 根据URL地址获取文件
*
* @param path URL网络地址
* @return File
*/
private static File getFileByHttpURL(String path) {
String newUrl = path.split("[?]")[0];
String[] suffix = newUrl.split("/");
//得到最后一个分隔符后的名字
String fileName = suffix[suffix.length - 1];
File file = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
file = File.createTempFile("report", fileName);//创建临时文件
URL urlFile = new URL(newUrl);
inputStream = urlFile.openStream();
outputStream = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != outputStream) {
outputStream.close();
}
if (null != inputStream) {
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
}
/**
* 通过documents4j 实现word转pdf -- linux 环境 需要有 libreoffice 服务
*
* @param wordFile 源文件
*/
public static String linuxDocuments4jWordToPdf(File wordFile, String pdfPath) {
// 获取文件的绝对路径和目录路径
String absolutePath = wordFile.getAbsolutePath();
String parentPath = wordFile.getParent();
// 构建LibreOffice的命令行工具命令
String commands = "libreoffice7.5 --headless --invisible --convert-to pdf "
+ absolutePath + " --outdir " + parentPath;
// 执行转换命令
try {
boolean result = executeLinuxCmd(commands);
if (result) {
// 转换成功,返回转换后的PDF文件
String pdfFilePath = parentPath + File.separator + wordFile.getName().replaceAll("\\.(docx?|\\w+)$", "") + ".pdf";
log.info(pdfFilePath);
return pdfPath;
} else {
return null;
}
} catch (Exception e) {
// 转换失败
log.error("Word文档转换为PDF失败,原因:执行命令时出现异常。", e);
return null;
}
}
/**
* 执行命令行
*
* @param cmd 命令行
* @return
* @throws IOException
*/
private static boolean executeLinuxCmd(String cmd) throws IOException {
// 执行命令行工具命令
Process process = Runtime.getRuntime().exec(cmd);
try {
process.waitFor();
} catch (InterruptedException e) {
log.error("执行 Linux 命令异常:", e);
return false;
}
return true;
}
}
如有错误,评论指出,作者改正
欢迎大家点赞、转发、评论
文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr
文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc
文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8
文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束
文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求
文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname
文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include<stdio.h>#include<string.h>#include<stdlib.h>#include<malloc.h>#include<iostream>#include<stack>#include<queue>using namespace std;typed_二叉树的建立
文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码
文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词
文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限
文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定
文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland