​ 做一个word转pdf的服务,采用grpc,使用libreoffice命令。

1.构建libreoffice镜像

FROM python:3.6

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN cd /etc/apt \
&& mv sources.list sources.list.bak \
&& echo "deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib \
deb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib \
deb http://mirrors.aliyun.com/debian-security stretch/updates main \
deb-src http://mirrors.aliyun.com/debian-security stretch/updates main \
deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib \
deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib \
deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib \
deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib" > sources.list
RUN apt-get update
RUN apt-get install -y libreoffice
COPY ./ /root/
RUN mv /root/simsun.ttc /usr/share/fonts && mv /root/simhei.ttf /usr/share/fonts && cd /usr/share/fonts && fc-cache -fv
# docker build -t libreoffice .
  1. 采用python3.6镜像
  2. 使用阿里源
  3. 安装libreoffice
  4. 解决中文乱码 加入中文字体

2.grpc服务端、客户端

  1. 创建proto配置文件 然后编译

  2. 服务端与客户端 采用二进制 数据进行传输

  • 服务端

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time : 2019/7/9 0009 16:41
    # @File : word2pdf_server_main.py
    # @author : dfkai
    # @Software: PyCharm # python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./data.proto import os
    import pathlib
    import time
    import traceback
    import uuid
    from concurrent import futures import grpc from proto_py import word2pdf_pb2, word2pdf_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24
    _HOST = os.environ.get("HOSTNAME", "localhost")
    _PORT = '8080' class FormatData(word2pdf_pb2_grpc.FormatDataServicer):
    def DoFormat(self, request, context):
    """
    proto 定义方法
    :param request:
    :param context:
    :return:
    """
    data = request.text
    doc_path, pdf_path, pdf_file_path = self.get_doc_pdf_path()
    with open(doc_path, "wb") as f:
    f.write(data)
    if self.word2pdf_linux(doc_path, pdf_path):
    try:
    with open(pdf_file_path, "rb") as f:
    pdf_data = f.read()
    except:
    traceback.format_exc()
    else:
    pdf_data = b"fail"
    return word2pdf_pb2.Data(text=pdf_data) def get_doc_pdf_path(self):
    """
    获取文件路径
    :return:
    """
    baseDir = os.getcwd()
    p = pathlib.Path(baseDir)
    u_name = str(uuid.uuid4()).replace("-", "")
    doc_name = u_name + ".docx"
    pdf_name = u_name + ".pdf"
    pdf_path = p / f"filepath/pdf/"
    doc_path = p / f"filepath/doc/{doc_name}"
    pdf_file_path = p / f"filepath/pdf/{pdf_name}"
    print(doc_path, pdf_path, pdf_file_path)
    return rf"{doc_path}", rf"{pdf_path}", rf"{pdf_file_path}" def word2pdf_win(self, doc_path, pdf_path):
    """
    windows 生成
    :param doc_path:
    :param pdf_path:
    :return:
    """
    from win32com import client
    import pythoncom
    pythoncom.CoInitialize()
    # word = client.Dispatch("Word.Application")
    word = client.DispatchEx("Word.Application")
    worddoc = word.Documents.Open(doc_path)
    try:
    worddoc.SaveAs(pdf_path, FileFormat=17)
    except Exception as e:
    print(e)
    return False
    finally:
    worddoc.Close()
    return True def word2pdf_linux(self, doc_path, pdf_path):
    """
    linux 生成 pdf ,利用 libreoffice 命令
    :param doc_path:
    :param pdf_path:
    :return:
    """
    try:
    os.system(f"soffice --headless --invisible --convert-to pdf {doc_path} --outdir {pdf_path} ")
    except:
    traceback.format_exc()
    return False
    return True def serve():
    """
    rpc 服务
    :return:
    """
    grpcServer = grpc.server(futures.ThreadPoolExecutor(max_workers=4))
    word2pdf_pb2_grpc.add_FormatDataServicer_to_server(FormatData(), grpcServer)
    grpcServer.add_insecure_port(_HOST + ':' + _PORT)
    grpcServer.start()
    try:
    while True:
    time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
    grpcServer.stop(0) if __name__ == '__main__':
    serve()
  • 客户端

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time : 2019/7/9 0009 16:40
    # @File : word2pdf_client_main.py
    # @author : dfkai
    # @Software: PyCharm
    import traceback
    import grpc
    from proto_py import word2pdf_pb2, word2pdf_pb2_grpc _HOST = 'localhost'
    _PORT = '8080' def run():
    file_name = "test"
    doc_name = file_name + '.doc'
    conn = grpc.insecure_channel(_HOST + ':' + _PORT)
    client = word2pdf_pb2_grpc.FormatDataStub(channel=conn)
    with open(doc_name, "rb") as f:
    data = f.read()
    response = client.DoFormat(word2pdf_pb2.Data(text=data))
    if response.text == b"fail":
    # 发送消息 生成失败
    pass
    else:
    pdf_name = file_name + f'.pdf'
    try:
    with open(pdf_name, "wb") as f:
    f.write(response.text)
    except:
    traceback.format_exc()
    # 发送消息 生成失败
    else:
    # 发送消息 生成成功
    pass if __name__ == '__main__':
    import time
    beg = time.time()
    run()
    end = time.time()
    print(end - beg)
  • proto配置文件

    syntax = "proto3";
    package example;
    service FormatData {
    rpc DoFormat(Data) returns (Data){}
    }
    message Data {
    bytes text = 1;
    }

    进入文件目录,构建命令:python -m grpc_tools.protoc -I. --python_out=./proto_py/ --grpc_python_out=./proto_py/ ./proto/word2pdf.proto

3.构建rpc服务端镜像

FROM libreoffice

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone COPY ./ /root/
WORKDIR /root/word2pdfRPC
RUN pip3 install -i https://mirrors.aliyun.com/pypi/simple/ -r requirments.txt
EXPOSE 8080
CMD python server_main.py
# docker build -t word2pdf .
# docker run -d -p 8080:8080 -v /root/data/word2pdf/:/root/word2pdfRPC/filepath/ --name word2pdf word2pdf
  • reuirements.txt

    futures==3.1.1
    grpcio==1.22.0
    grpcio-tools==1.22.0
    protobuf==3.8.0

参考、推荐:

  1. protobuf和thrift对比
  2. Language Guide (proto3)
  3. Encoding

grpc 之 word2pdf使用的更多相关文章

  1. gRPC源码分析1-SSL/TLS

    引子 前几天看到微信后台团队分享了TLS相关文章,正好gRPC里TLS数据加密是很重要的一块,于是整理出了这篇文章. 在gRPC里,如果仅仅是用来做后端微服务,可以考虑不加密.本文太长,先给个大纲. ...

  2. gRPC源码分析2-Server的建立

    gRPC中,Server.Client共享的Class不是很多,所以我们可以单独的分别讲解Server和Client的源码. 通过第一篇,我们知道对于gRPC来说,建立Server是非常简单的,还记得 ...

  3. gRPC源码分析0-导读

    gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...

  4. 谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC

    Google 刚刚开源了grpc,  一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobuf 本身虽然提供了RPC  的定义语法,但是一直以来,Google 只开 ...

  5. gRPC .NET Core跨平台学习

    前些天发布gRPC C# 学习,在.NET Framework 中使用gRPC ,今天来学习 .NET Core gRPC. gRPC 的.NET Core 包在NuGet 上发布了,结合.NET C ...

  6. gRPC C#学习

    前些天gRPC 发布1.0 版本,代表着gRPC 已经正式进入稳定阶段. 今天我们就来学习gRPC C# .而且目前也已经支持.NET Core 可以实现完美跨平台. 传统的.NET 可以通过Mono ...

  7. .net core 用grpc实现微服务

    GRPC 是Google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架.提供跨语言.跨平台支持.以下以.NET Core 使用控制台.docker中演示如何使用G ...

  8. rpc框架之gRPC 学习 - hello world

    grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的r ...

  9. Android开发笔记之《远程控制(MQTT|mosquitto) && (ProtocalBuffer | GRPC)》

    Android推送方案分析(MQTT/XMPP/GCM): http://www.open-open.com/lib/view/open1410848945601.htmlMQTT官网: http:/ ...

随机推荐

  1. android自定义控件onMeasure方法

    1.自定义控件首先定义一个类继承View 有时,Android系统控件无法满足我们的需求,因此有必要自定义View.具体方法参见官方开发文档:http://developer.android.com/ ...

  2. JDK8--02:为什么要使用lambda

    lambda是一个匿名函数,我们可以把lambda理解为一个可以传递的代码(将代码像数据一样传递),可以写出更简洁更灵活的代码.首先看一下原来的匿名内部类实现方式(以比较器为例) //原来的匿名内部类 ...

  3. WTL中GDI+支持资源文件加载

    WTL中GDI+支持资源文件加载 分类: WTL WTL gdi+ gdi+2013-04-22 17:16 78人阅读 评论(0) 收藏 举报 WTLGDI+c++ 今天遇到一个小问题困扰了.就是G ...

  4. java使字符串的数字加一

    /** * 字符串+1方法,该方法将其结尾的整数+1,适用于任何以整数结尾的字符串,不限格式,不限分隔符. * @author zxcvbnmzb * @param testStr 要+1的字符串 * ...

  5. 我用shell写了个mud游戏:武林群侠传

    零.前言 学习shell的时候,无聊的我,写了个简单版的文字mud,暂且叫武林群侠传吧.可能90后都不知道文字mud是什么了--哈哈 壹.效果 先看下效果吧,GIF图如下 文字效果如下: [root@ ...

  6. 洛谷 P1186 【玛丽卡】

    这道题题目真的想吐槽一下...是在机房同学的解释下才看懂的.就是让你求在可以删一条边的情况下,并且删后保证可以到达终点时,求删了后的最大的最短路径. 70分暴力思路: 枚举删边,然后跑一下最短路即可, ...

  7. 用户不在sudoers文件中怎么办,ziheng is not in the sudoers file解决方法

    sudo是linux系统中,用来执行需要权限命令,但是一些朋友使用sudo时,出现下面的错误“ziheng is not in the sudoers file. This incident will ...

  8. postcss.config.js not found

    https://github.com/ElemeFE/element/issues/10249

  9. 虚拟机中Linux环境搭建

    Linux系统搭建 作为一名软件测试资深工程师,在日常工作中离不开对测试环境的操作.我们测试的软件,系统都是部署在linux系统环境上,我们掌握Linux系统的日常操作是非常必要的.那么在学习Linu ...

  10. Java实现 第十一届蓝桥杯——超级胶水(渴望有题目的大佬能给小编提供一下题目,讨论群:99979568)

    PS: 好久没写过算法题了,总感觉自己写的思路没问题,但是结果就是不对,希望哪位大佬有时间能给找找问题 超级胶水 小明有n颗石子,按顺序摆成一排,他准备用胶水将这些石子黏在一起. 梅克什字有自己的重量 ...