精华内容
下载资源
问答
  • 本文实例讲述了php如何生成word并下载的具体实例。分享给大家供大家参考,具体如下: 1.前端代码 <!DOCTYPE html> <html> <head> <title>PHP生成Word文档</title> <meta charset=...
  • 经典行业的应用以及各行业的字体规定和页面标准设置
  • PhpWord按word模板填充数据后下载下载 phpword模板填充下载(会在服务器生成一个word)修改后 下载 phpword composer require phpoffice/phpword 模板填充下载(会在服务器生成一个word) $phpword=new PhpWord(); ...

    下载 phpword

    composer require phpoffice/phpword
    

    模板填充下载(会在服务器生成一个word)

    $phpword=new PhpWord();
    $template=$phpword->loadTemplate('***.doc');//读取word模板
    $template->setValue('name','test');//填充数据
    $filename = 'test.doc';
    $template->saveAs($filename); //另存为新word文档,根据模板和变量生成了新的文档
    
    $file = fopen($filename, "rb");//以只读和二进制模式打开文件
    Header("Content-type: application/octet-stream"); //告诉浏览器这是一个文件流格式的文件
    Header("Accept-Ranges: bytes");  //请求范围的度量单位
    Header("Accept-Length: " . filesize($filename)); //Content-Length是指定包含于请求或响应中数据的字节长度
    //用来告诉浏览器,文件是可以当做附件被下载,下载后的文件名称为$file_name该变量的值。
    Header("Content-Disposition: attachment; filename=$filename");
    echo fread($file, filesize($filename));   //读取文件内容并直接输出到浏览器
    fclose($file);
    exit ();
    

    转载来源:https://blog.csdn.net/Alencai/article/details/103503483

    补充修改,避免数据填充后在服务器生成文件

    https://blog.csdn.net/qq_45504289/article/details/107250998

    展开全文
  • 文章目录 引言 一、word模板准备 二、WordDemo实现 1、mainwindow.ui 2、mainwindow.h 3、mainwindow.cpp 三、实现效果 引言 在QT5.3中,在.pro使用的是:QT += widgets gui axcontainer 来使用ActiveQt框架中的...

    引言

    在QT5.3中,在.pro使用的是:QT += widgets gui axcontainer 来使用ActiveQt框架中的QAxContainer模块(Qt4版本添加Qt += qaxcontainer)=),所以在项目在头文件中包含QAxWidget和QAxObject。

    简单介绍ActiveQt框架由两个模块组成:
    QAxContainer模块允许我们使用COM对象并且可以在Qt应用程序中嵌入QActive控件。
    QAxServer模块允许我们导出使用Qt编写的自定义的COM对象和Active控件。

    一、word模板准备

    模板的准备至关重要,而其中更重要的是模板中书签的设置命名,因为接下来的程序代码中,程序就是根据书签的名字,来定位word文档中的位置,从而进行数据的插入修改

    当设计好表格,并且设计好书签的名称,便将文档保存为 .dot格式

    在这里插入图片描述
    在这里插入图片描述

    二、WordDemo实现

    代码中都有详尽的注释

    1、mainwindow.ui

    在这里插入图片描述

    在这里插入图片描述

    2、mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        void init_UI();		//初始化界面函数
        void clear_UI();	//重置界面函数
    
    
    private slots:
        void reshow();			//重置界面的槽函数
        void create_word();		//创建报表的槽函数
    
    private:
        Ui::MainWindow *ui;
    
    
    
    };
    #endif // MAINWINDOW_H
    
    

    3、mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QAxObject>
    #include <QAxWidget>
    #include <QMessageBox>
    #include <QFileDialog>
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        init_UI();
    
        connect(ui->btu_create,SIGNAL(clicked(bool)),this,SLOT(create_word()));
        connect(ui->btu_create,SIGNAL(clicked(bool)), this, SLOT(reshow()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::create_word()
    {
        //新建一个word应用程序
        QAxWidget *word = new QAxWidget("Word.Application",0,Qt::MSWindowsOwnDC);
        //并设置为不可见
        word->setProperty("Visible",false);
        //获取所有的工作文档
        QAxObject *documents = word->querySubObject("Documents");
        //以test2.dot为模板新建一个文档
        documents->dynamicCall("Add(QString)",QString::fromLocal8Bit("E:/MyQtWorkSpace/Word/test2.dot"));
        //获取当前激活的文档
        QAxObject *document = word->querySubObject("ActiveDocument");
    
        //获取文档中名字为equ的标签
        QAxObject *bookmark_equ = document->querySubObject("Bookmarks(QVariant)","equ");
        //选中标签,将字符textg插入到标签位置
        if(!bookmark_equ->isNull())
        {
            QString sText=ui->lineEdit_equ->text();                          //此处为替换内容
            qDebug()<<sText;
            bookmark_equ->dynamicCall("Select(void)");                             //选中要选中的区域
            bookmark_equ->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
        }
    
        //获取文档中名字为temp的标签
        QAxObject *bookmark_temp = document->querySubObject("Bookmarks(QVariant)","temp");
        //选中标签,将字符textg插入到标签位置
        if(!bookmark_equ->isNull())
        {
            QString pText=ui->lineEdit_temp->text();                          //此处为替换内容
            bookmark_temp->dynamicCall("Select(void)");                             //选中要选中的区域
            bookmark_temp->querySubObject("Range")->setProperty("Text",pText);      //进行替换操作
        }
    
        //获取文档中名字为bas的标签
        QAxObject *bookmark_bas = document->querySubObject("Bookmarks(QVariant)","bas");
        //选中标签,将字符textg插入到标签位置
        if(!bookmark_equ->isNull())
        {
            QString bText=ui->lineEdit_bas->text();                                 //此处为替换内容
            bookmark_bas->dynamicCall("Select(void)");                             //选中要选中的区域
            bookmark_bas->querySubObject("Range")->setProperty("Text",bText);      //进行替换操作
        }
        qDebug()<<"方法";
    
    
    
        //修改word中的表格
        QString sheethead = "序号";
        for(int j=1;j<=4;j++)
        {
            QString addrowhead=QString("%1").arg(j);
            QString sheetheadnumber = QString("%1%2").arg(sheethead).arg(addrowhead);
            qDebug()<<sheetheadnumber;
    
            QAxObject *sheethead = document->querySubObject("Bookmarks(QVariant)",sheetheadnumber);
            QString sheettexthead=ui->tableWidget->item(j-1,0)->text();                             //此处为替换内容
            sheethead->dynamicCall("Select(void)");                                                 //选中要选中的区域
            sheethead->querySubObject("Range")->setProperty("Text",sheettexthead);                  //进行替换操作
        }
    
        QString sheetfrist = "数据";
        for(int i=1;i<=4;i++)
        {
            for(int j=1;j<5;j++)
            {
                QString addrow=QString("%1").arg(i);
                QString addcolum=QString("%1").arg(j);
    
                QString sheetlabel = QString("%1%2%3").arg(sheetfrist).arg(addrow).arg(addcolum);
                qDebug()<<sheetlabel;
    
                QAxObject *sheetdata = document->querySubObject("Bookmarks(QString)",sheetlabel);
                QString sheettext=ui->tableWidget->item(i-1,j)->text();                     //此处为替换内容,必须要加入.text().这样返回值才会正确
                sheetdata->dynamicCall("Select(void)");                                     //选中要选中的区域
                sheetdata->querySubObject("Range")->setProperty("Text",sheettext);          //进行替换操作
            }
        }
    
    
       //将文件保存为doc,同样可以生成docx文档
        QString pathsave = QFileDialog::getSaveFileName(this,"Save","../","word(*doc)");
        if(pathsave.isEmpty()==true)
        {
            return;
        }
        document->dynamicCall("SaveAs(const QString&))",QDir::toNativeSeparators(pathsave));
        document->dynamicCall("Close (boolean)",false);
        word->dynamicCall("Quit()");
        QMessageBox::warning(this,"完成","文件已经保存",QMessageBox::Yes);
    
    }
    
    void MainWindow::init_UI()
    {
        int col = 5;
        int row = 4;
        ui->tableWidget->setColumnCount(col);
        ui->tableWidget->setRowCount(row);
        QStringList header; //表头写入表格
        header <<QString::fromUtf8("序号")
              <<QString::fromUtf8("测试数据1")<<QString::fromUtf8("测试数据2")
             <<QString::fromUtf8("测试数据3")<<QString::fromUtf8("测试数据4");
        ui->tableWidget->setHorizontalHeaderLabels(header);
        ui->tableWidget->horizontalHeader()->setStretchLastSection(true);   //自动调整宽度
        ui->tableWidget->verticalHeader()->hide();
    
        QString num[4]={"1","2","3","4"};
        for(int i=0;i<row;i++)  //序号填充
        {
            ui->tableWidget->setItem(i,0,new QTableWidgetItem(num[i]));
        }
        QString data[4][4]={{"5","7","8","6"},
                            {"4","6","5","9"},
                            {"7","5","5","6"},
                            {"8","3","4","6"}};
        for(int i=0;i<4;i++)    //随机数据填充
        {
            for(int j=1;j<5;j++)
            {
                ui->tableWidget->setItem(i,j,new QTableWidgetItem(data[i][j]));
            }
        }
    }
    
    void MainWindow::clear_UI()
    {
        ui->lineEdit_bas->clear();
        ui->lineEdit_equ->clear();
        ui->lineEdit_temp->clear();
    }
    
    void MainWindow::reshow()
    {
        clear_UI();
        this->show();
    }
    
    

    三、实现效果

    修改数据

    在这里插入图片描述

    点击生成

    在这里插入图片描述

    点击保存

    在这里插入图片描述

    点击Yes

    在这里插入图片描述

    完成效果

    在这里插入图片描述
       

    如有不足之处,还望指正 1


    1. 如果对您有帮助可以点赞、收藏、关注,将会是我最大的动力 ↩︎

    展开全文
  • Java根据word模板生成word文档之后台解析和实现及部分代码(一)后台主要工作是解析XML定义的标签文件,并获取到数据集,放入到Map中,然后调用Jacob.jar中提供的相关方法来实现替换。首先想多说一句就是jacob会每次...

    Java根据word模板生成word文档之后台解析和实现及部分代码(一)

    后台主要工作是解析XML定义的标签文件,并获取到数据集,放入到Map中,然后调用Jacob.jar中提供的相关方法来实现替换。首先想多说一句就是

    jacob会每次生成word报告时都会启动一个office word进程,替换完毕之后

    需要关闭掉这个进程,如果有死掉的word进程有可能会影响word的生成。这些具体做火这调试过程中就会发现这个问题的。

    还需要说明一点,解析XML有很多种方式,自己挑选自己熟悉的就行了,我采用jdom,当时想的没有这么负责,所以写代码也没有怎么重构,需要重新整理,主要方法我会贴出来。

    那么我就从头到尾的说一下,调用生成报告时,后台的整个调用过程是怎么样的,是如何运转的?

    首先访问web应用地址:http://192.16.3.22/demo/DocInfo!createDoc.action

    这样我提交一个方法

    action方法,这个方法首先是在web应用服务器上的,然后进入action中的createDoc方法,同时你需要获取到从方法传过来的相关参数,

    比如:sql中定义的那个查询条件,报告类型等参数。

    (在去调用生成报告的方法中,可能你还需要加入一些判断,如是否已经生成过报告啊,或者最新报告的版本啊,因为我们都是既保存word报告文档又会在数据库中插入一条记录,方便查询),这样就开始了:

    首先是action的createDoc方法:

    [java]

    view plain

    copy

    /**

    * 通过HttpCient调用报告服务器的方法生成报告 DOC

    */

    public

    String createDoc()

    throws

    Exception {

    //定义放回成功与否的判断码

    String prMsg=""

    ;

    // 获取当前登录的用户

    UserVo userVo = CommonUtils.getUserMessage();

    //获取模版类型

    docType = Struts2Utils.getParameter("docType"

    );

    //重新创建文档

    String creatOrnot = Struts2Utils.getParameter("creatOrnot"

    );

    //获取组组编号参数

    workgroupId = Struts2Utils.getParameter("workgroupId"

    );

    //获取评估用例实例ID参数

    evtcaseInstId = Struts2Utils.getParameter("evtcaseInstId"

    );

    if

    (CommonUtils.isNotNull(docType)){

    //获取项目Id

    projectId = Struts2Utils.getParameter("projectId"

    );

    if

    (!CommonUtils.isNotNull(projectId)){

    if

    (CommonUtils.isNotNull(

    this

    .getIdFromSession(

    "PM_PROJECTID"

    ))){

    projectId = this

    .getIdFromSession(

    "PM_PROJECTID"

    ).toString();

    }else

    {

    Struts2Utils.getRequest().setAttribute("msg"

    ,

    "请先选择项目!"

    );

    }

    }

    if

    (CommonUtils.isNotNull(projectId)){

    prMsg = infoSystemDescService.downloadFileByUrl(projectId, userVo.getUserId(), workgroupId, evtcaseInstId, docType, creatOrnot);

    }

    }

    return

    "docList"

    ;

    }

    注:在我贴出来的代码中,能看懂就行了,有些不用管他(可能是其他业务方面的判断),关于最后返回的prMsg---代表各种状态

    主要表示成功与否或者是出错的信息。

    接着我贴出service层的方法downloadFileByUrl

    [java]

    view plain

    copy

    
     

    "code"

    class

    =

    "java"

    >

    
     

    "code"

    class

    =

    "java"

    >

    /**

    * 功能:

    * 1.(生成报告文档)

    * 2.保存指定URL的源文件到指定路径下

    * @param projectId

    * @param userId

    * @param workgroupId

    * @param evtcaseInstId

    * @param docType

    * @param creatOrnot

    * @return

    * @throws Exception

    */

    @SuppressWarnings

    (

    "deprecation"

    )

    public

    synchronized

    String downloadFileByUrl(String projectId,String userId,String workgroupId,String evtcaseInstId,String docType,String creatOrnot)

    throws

    Exception {

    String msg = "1"

    ;

    //"1":默认为创建成功的提示信息 "2":标识创建失败

    String srcUrl = ""

    ;

    //报告服务器的执行路径

    HttpResponse response = null

    ;

    FileOutputStream out = null

    ;

    HttpClient httpclient = null

    ;

    HttpGet httpget = null

    ;

    long

    time1 = System.currentTimeMillis();

    //获取保存后的路径

    TProjDoc projDoc = projectDocDao.findFileByType(userId, Integer.parseInt(docType), Long.parseLong(projectId), workgroupId,evtcaseInstId);

    if

    (projDoc ==

    null

    || (projDoc !=

    null

    && CommonUtils.isNotNull(creatOrnot) && creatOrnot.equals(

    "1"

    ))){

    //FT_任务编号_[FID]

    try

    {

    //获取报告服务器的执行路径

    srcUrl = xmlPathDef.getActionUrl(docType, projectId,userId,workgroupId,evtcaseInstId);

    HttpParams httpParams = new

    BasicHttpParams();

    // 设置最大连接数

    ConnManagerParams.setMaxTotalConnections(httpParams, 1

    );

    // 设置获取连接的最大等待时间

    //ConnManagerParams.setTimeout(httpParams, 6000);

    // 设置每个路由最大连接数

    ConnPerRouteBean connPerRoute = new

    ConnPerRouteBean(

    1

    );

    ConnManagerParams.setMaxConnectionsPerRoute(httpParams,connPerRoute);

    // 设置连接超时时间

    HttpConnectionParams.setConnectionTimeout(httpParams, 6000

    );

    // 设置读取超时时间

    if

    (docType.toString().equals(XmlPathDef.SPOTTEST_DOC) && docType.toString().equals(XmlPathDef.FTEST_DOC)){

    HttpConnectionParams.setSoTimeout(httpParams, 2400000

    );

    }else

    {

    HttpConnectionParams.setSoTimeout(httpParams, 600000

    );

    }

    SchemeRegistry registry = new

    SchemeRegistry();

    registry.register(new

    Scheme(

    "http"

    , PlainSocketFactory.getSocketFactory(),

    80

    ));

    registry.register(new

    Scheme(

    "https"

    , SSLSocketFactory.getSocketFactory(),

    443

    ));

    ClientConnectionManager connectionManager = new

    ThreadSafeClientConnManager(httpParams, registry);

    httpclient = new

    DefaultHttpClient(connectionManager, httpParams);

    httpget = new

    HttpGet(srcUrl);

    //执行返回

    response = httpclient.execute(httpget);

    //如果是本机既当服务器,又当报表服务器,那么就只生成一遍

    String ipvalues = xmlPathDef.getRepUrl();

    if

    (CommonUtils.isNotNull(ipvalues)){

    if

    (ipvalues.indexOf(

    ":"

    ) != -

    1

    ){

    ipvalues = ipvalues.substring(0

    ,ipvalues.lastIndexOf(

    ":"

    ));

    }

    }

    HttpEntity entity = response.getEntity();

    //获取保存后的路径

    projDoc = projectDocDao.findFileByType(userId,Integer.parseInt(docType), Long.parseLong(projectId), workgroupId,evtcaseInstId);

    String filePath = ""

    ;

    if

    (projDoc !=

    null

    )

    filePath = projDoc.getPath();

    if

    (CommonUtils.isNotNull(filePath)){

    String basepath = XmlPathDef.getBasePath();

    String outFilePath = (basepath + filePath).replaceAll("\\\\", "

    \\/");

    XmlPathDef.isExists(outFilePath);

    File wdFile = new

    File(outFilePath);

    out = new

    FileOutputStream(wdFile);

    int

    l;

    byte

    [] tmp =

    new

    byte

    [

    2048

    ];

    while

    ((l = instream.read(tmp)) != -

    1

    ) {

    out.write(tmp, 0

    , l);

    }

    out.flush();

    out.close();

    System.out.println("****************************** "

    );

    System.out.println(""

    );

    System.out.println("*************** 恭喜! 报告创建成功   结束   ***************"

    );

    System.out.println(""

    );

    }else

    {

    msg = "8"

    ;

    //说明word创建成功,但是数据没有保存成功

    response = null

    ;

    }

    }else

    {

    msg = "2"

    ;

    }

    } catch

    (ClientProtocolException e) {

    msg = "7"

    ;

    e.printStackTrace();

    } catch

    (IOException e) {

    msg = "7"

    ;

    logger.error("数据库报告服务器地址配置错误或网络不通!!2.连接是否超时"

    + e.getMessage());

    e.printStackTrace();

    }finally

    {

    if

    (out!=

    null

    ){

    try

    {

    out.close();

    } catch

    (IOException e) {

    msg = "7"

    ;

    logger.error("数据库报告服务器地址配置错误或网络不通!!2.连接是否超时"

    + e.getMessage());

    e.printStackTrace();

    }

    }

    }

    }

    long

    time2 = System.currentTimeMillis();

    long

    numTime = time2 - time1;

    if

    (docType.toString().equals(XmlPathDef.SPOTTEST_DOC) && docType.toString().equals(XmlPathDef.FTEST_DOC)){

    if

    (numTime >=

    2401000

    ){

    msg = "9"

    ;

    }

    }else

    {

    if

    (numTime >=

    601000

    ){

    msg = "9"

    ;

    }

    }

    System.out.println(""

    );

    String loggerinfo = "********* 报告类型为 :"

    +  docType +

    " 执行时间为: "

    + (time2 - time1) /

    1000

    +

    " 秒!***************"

    ;

    System.out.println(loggerinfo);

    System.out.println(""

    );

    System.out.println("*****************************"

    );

    logger.info(loggerinfo);

    return

    msg;

    }

    这个方法还有待优化和调整,现在我主要说明他的作用:

    首先

    使用了synchronized 关键字

    意思说使用同步的方式,让每次只有一个线程运行这个方法(其实如果是大数量的并发,就不能这样写了,自己去摸索吧)。然后在方法体中,使用了一个

    httpclient技术,这个主要是调用远程的服务返回对象流,在我这里就是调用另外一个服务器的代码,去生成报告,

    然后

    将word报告的流返回来就ok,如果不明白httpclient的用法,请上网学一下,具体我就不说了。(下节我会贴出相应的代码

    )

    最后

    通过httpclient的返回流写成word文档就行了(其实里面还有一些判断什么的,比如:最后返回流是否是word流啊,什么的 都需要判断的,我都去掉了,代码太多),返回一个状态码给action就完毕。

    展开全文
  • 在项目中很容易会遇到需要动态生成pdf的应用场景,其实现方式也比较多 由于项目的关系,对于这种组件性的开发方式我想的是怎么方便怎么来,怎么快就怎么来 在咨询了之前做政务系统的同学后,他们都一致推荐我使用...

    在项目中很容易会遇到需要动态生成pdf的应用场景,其实现方式也比较多

    由于项目的关系,对于这种组件性的开发方式我想的是怎么方便怎么来,怎么快就怎么来

    在咨询了之前做政务系统的同学后,他们都一致推荐我使用aspose框架来实现,因为它的效率高并且简单方便使用

    在看了下aspose的官网和对demo简单体验了之后感觉确实很方便,为了后面项目中万一又遇到有需要的场景可以信手拈来,这里我简单在此处记录一下

    下载地址

    https://downloads.aspose.com/words/java

    选择版本:Aspose.Words for Java 19.1

    (之所以选择那个版本,是因为网上有很多这个版本的pj教程,太新的担心pj不了,当然不pj也可以用但是有水印)

    如果直接下载jar的话也可通过aspose官方的maven仓库地址进行下载:

    https://repository.aspose.com/repo/com/aspose/aspose-words/19.1/aspose-words-19.1-jdk16.jar

    pj教程:

    https://www.jianshu.com/p/be0cbdc389cc

    也可以直接下载已破解好的jar,如果自己能找到的话

    使用示例

    这里演示一个目前我的项目中可能需要满足的一个需求,通过一个word模板生成pdf,动态填充word中的内容,同时支持生成多个pdf但要求pdf合并到一个pdf中

    添加maven依赖

    将下载好的jar放到项目中,然后添加依赖

            <!--aspose-words依赖,直接依赖本地项目中的jar-->
            <dependency>
                <groupId>com.aspose</groupId>
                <artifactId>aspose-words</artifactId>
                <version>aspose-words-19.1-jdk16.jar</version>
                <scope>system</scope>
                <systemPath>${pom.basedir}/libs/aspose-words-19.1-jdk16-crack.jar</systemPath>
            </dependency>
    

    如果用本地jar打包时记得添加资源配置:

        <build>
            <resources>
                <resource>
                    <directory>libs</directory>
                    <targetPath>BOOT-INF/lib/</targetPath>
                    <includes>
                        <include>**/*.jar</include>
                    </includes>
                </resource>
            </resources>
        </build>
    

    word模板准备

    我们的最终目的是生成pdf,但为了方便还是先通过word模板生成word之后再输出为pdf。

    为了排版方便建议还是使用word中的表格来进行排版,对于可变的地方可以添加【文字型窗体域】便于后面程序的文字进行填充
    word模板编辑
    在word模板准备好了之后就可以直接开始写代码了

    测试代码

    import com.aspose.words.*;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.time.format.DateTimeFormatter;
    import java.util.ArrayList;
    import java.util.Date;
    
    /**
     * @author puhaiyang
     * @date 2020/10/11 12:12
     * 测试aspose生成pdf工具类
     */
    public class AsposeWordsUtils {
        /**
         * Word转PDF操作
         *
         * @param doc        源文件
         * @param targetFile 目标文件
         */
        public static void doc2pdf(Document doc, String targetFile) {
            try {
                long old = System.currentTimeMillis();
                //新建一个空白pdf文档
                File file = new File(targetFile);
                FileOutputStream os = new FileOutputStream(file);
                //全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
                doc.save(os, SaveFormat.PDF);
                os.close();
                long now = System.currentTimeMillis();
                //转化用时
                System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private static class UserInfo {
            public UserInfo(String userNumber, String userName, String depaName, String desc, Date pubDate) {
                this.userNumber = userNumber;
                this.userName = userName;
                this.depaName = depaName;
                this.desc = desc;
                this.pubDate = pubDate;
            }
    
            private String userNumber;
            private String userName;
            private String depaName;
            private String desc;
            private Date pubDate;
    
            public String getUserNumber() {
                return userNumber;
            }
    
            public void setUserNumber(String userNumber) {
                this.userNumber = userNumber;
            }
    
            public String getUserName() {
                return userName;
            }
    
            public void setUserName(String userName) {
                this.userName = userName;
            }
    
            public String getDepaName() {
                return depaName;
            }
    
            public void setDepaName(String depaName) {
                this.depaName = depaName;
            }
    
            public String getDesc() {
                return desc;
            }
    
            public void setDesc(String desc) {
                this.desc = desc;
            }
    
            public Date getPubDate() {
                return pubDate;
            }
    
            public void setPubDate(Date pubDate) {
                this.pubDate = pubDate;
            }
        }
    
        public static void main(String[] args) throws Exception {
            ArrayList<UserInfo> userInfoList = getUserInfoList();
            //模板word
            String template = "C:/Users/ping/Desktop/temp/aspose/test/forTest.docx";
    
            Document firstDocument = null;
            for (UserInfo userInfo : userInfoList) {
                //目标word
                Document document = new Document(template);
                Range range = document.getRange();
                range.replace("ygbh", userInfo.getUserNumber(), new FindReplaceOptions());
                range.replace("ygxm", userInfo.getUserName(), new FindReplaceOptions());
                range.replace("szbm", userInfo.getDepaName(), new FindReplaceOptions());
                range.replace("zygx", userInfo.getDesc(), new FindReplaceOptions());
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDateTime localDateTime = LocalDateTime.ofInstant(userInfo.getPubDate().toInstant(), ZoneId.systemDefault());
                range.replace("bfrq", formatter.format(localDateTime), new FindReplaceOptions());
                if (firstDocument == null) {
                    firstDocument = document;
                } else {
                    //添加文档
                    firstDocument.appendDocument(document, ImportFormatMode.KEEP_DIFFERENT_STYLES);
                }
            }
            doc2pdf(firstDocument, "C:/Users/ping/Desktop/temp/aspose/test/descForTest.pdf");
        }
    
        private static ArrayList<UserInfo> getUserInfoList() {
            ArrayList<UserInfo> userInfoList = new ArrayList<UserInfo>();
            userInfoList.add(new UserInfo("666001", "海洋哥",
                    "滑水部-酱油项目组-基础架构组",
                    "研究如何滑水及如何深入打酱油,对如何平滑滑水取得了重要贡献", new Date()));
            userInfoList.add(new UserInfo("666002", "帅哥",
                    "核心项目事业部-超级潜水部-默默潜水研究组-项目三组",
                    "对如何潜水取得了重要贡献", new Date()));
            return userInfoList;
        }
    }
    

    整体来看代码还是很少的,写完后直接运行跑一下

    输出结果

    输出文件
    输出文件
    生成的pdf文件预览
    生成的pdf文件预览
    效果还是可以的,文字该换行显示的还是换行显示了,效果不错代码执行效率也很快,非常简单。

    以后再遇到要求项目中实现动态生成PDF简直就是分分钟的事呀!nice~

    linux下导出pdf乱码解决办法

    如果在windows下导出pdf一切正常,但在linux下导出pdf中文乱码了,则需要通过添加字体文件并在aspose的代码中指定所在的字体文件

    //指定字体目录
    FontSettings.getDefaultInstance().setFontsFolder("/opt/user/otherfonts/", false);
    //执行保存
    doc.save(pdfPath);
    

    具体办法是先找到字体对应的字体文件,在windows不报错的话就从windows上先找下, windows的字体文件都在这个目录下

    C:\Windows\Fonts\

    方式一,直接部署方式

    找到对应的字体然后拷贝到linux某个目中即可

    方式二,docker部署方式

    但是如果是docker的话,则可以通过volume映射字体目录或通过Dockerfile直接将字体打在docker镜像中,如果打在镜像中的话会导致镜像文件很大

    方式三,通过k8s方式

    如果是通过kubernetes来部署的项目可以通过pvc来搞定,但如果没得对应的文件服务器,则可以用过init-containers配合emptyDir类型的volumes来解决,参考地址:https://kubernetes.io/docs/concepts/workloads/pods/init-containers/

    {
        "template": {
            "spec": {
                "containers": [
                    {
                        "image": "xxxxxxxxxxxxxxxxxxxx",
                        "volumeMounts": [
                            {
                                "mountPath": "/opt/user/otherfonts",
                                "name": "font-depend"
                            }
                        ]
                    }
                ],
                "initContainers": [
                    {
                        "command": [
                            "sh",
                            "-c",
                            "set -ex;mkdir -p /vmfontsdepend/fonts;cp -r /otherfonts/* /vmfontsdepend/fonts;"
                        ],
                        "image": "ccr.ccs.tencentyun.com/haiyang/font-depend-image:1.0.0",
                        "imagePullPolicy": "IfNotPresent",
                        "name": "init-font-depends",
                        "volumeMounts": [
                            {
                                "mountPath": "/vmfontsdepend/fonts",
                                "name": "font-depend"
                            }
                        ]
                    }
                ],
                "volumes": [
                    {
                        "emptyDir": {},
                        "name": "font-depend"
                    }
                ]
            }
        }
    }
    

    其中ccr.ccs.tencentyun.com/haiyang/font-depend-image:1.0.0的Dockerfile为:

    FROM alpine:3.8
    LABEL maintainer="puhaiyang"
    ADD fonts/* /otherfonts/
    

    fonts目录下为需要导入的字体文件


    参考资料

    查找并替换docx的中文字(模板生成)

    https://github.com/aspose-words/Aspose.Words-for-Java/blob/master/Examples/src/main/java/com/aspose/words/examples/quickstart/FindAndReplace.java

    多个docx文档合并为一个(文档合并)

    https://github.com/aspose-words/Aspose.Words-for-Java/blob/master/Examples/src/main/java/com/aspose/words/examples/quickstart/AppendDocuments.java

    docx转为pdf

    https://github.com/aspose-words/Aspose.Words-for-Java/blob/master/Examples/src/main/java/com/aspose/words/examples/loading_saving/ConvertToPDF.java

    展开全文
  • 制造题库所需Word模板需要填充数据的地方使用 ${pid} 代替。将这个word选择另存为,保存格式选择为xml,然后将这个xml放到项目的ftl目录下,后缀名改为.ftl 。2.配置数据库项目中使用了hibernate,表结构可以自动生成...
  • Word2010新功能、Word2010文档基本操作技巧、Word2010文字录入与编辑技巧、Word2010表格编辑技巧、Word2010图片编辑技巧、Word2010数据与图表应用技巧、Word2010图文格式设置技巧、Word2010段落格式设置技巧、Word...
  • word 常规模板设置

    万次阅读 2016-08-17 20:02:12
    word作为office的一部分,是微软提供的办公文档写作软件,这个很重要,因为他会提供除了文字编辑的功能之外,还附带很多提高工作效率的自动化功能,这才是专业办公文档写作软件的“专业”所在。当然,要提高协同工作...
  • Java自动生成带图片、富文本、表格等的word文档使用技术freemark+jsoup生成mht格式的伪word文档,已经应用项目中,确实是可行的,无论是富文本中是图片还是表格,都能在word中展现出来使用jsoup解析富文本框,将其中...
  • 水利水电 WORD EXCEL PPT 2016办公应用从入门到精通配套光盘,内含2330个办公应用图片素材,精华实用办公模板1000套及各章节实例文件
  • 软件的需求就是根据自己的需要往一个固定格式的word表格模板中添加文字或者图片,然后按照自己的需要生成新的word文档并查看。 上网找了很多关于在android环境下如何解析office文档的博客,发现一些比较好的例如POI...
  • C# 根据Word模板,填写内容

    千次阅读 2017-05-07 17:51:24
    适合模板写入 今天正好有人问我,怎么生成一个报表式的Word文档。 就是文字的样式和位置相对固定不变,只是里面的内容从数据中读取。   我觉得类似这种的一般用第三方报表来做比较简便。但既然要求了...
  • 使用C#操作word模板

    千次阅读 2017-06-30 15:02:08
    前段时间在做项目时,系统中有一个功能模块,内容是在线填写资料并保存成word...首先,我们先制作完一份word模板文件。  ①打开word2010,制作如下表格→插入书签→保存成word模板文档(Student.dot):  
  • 计算机应用类word应用文写作大全计算机应用类word应用文写作大全篇一:常用应用文写作格式Word模板常用应用文写作格式一、“通知”的写作格式通知的功能:通知适用于批转下级机关的公文,转发上级机关和不相隶属机关...
  • 导出word使用技术 https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html https://www.docx4java.org/trac/docx4j 官网 https://github.com/plutext/docx4j/tree/master/docx4j-samples-docx4j 例子 ...
  • 使用 poi 根据 word 模板生成 word 文件

    千次阅读 2015-11-17 17:49:28
    例子是一个 maven 项目,要引入 poi 的依赖片段如下: <groupId>org.apache.poi <artifactId>poi <version>3.13 </dependency><!-- 支持Word文档的操作 --> <group
  • Java 将xml模板动态填充数据转换为word文档

    万次阅读 多人点赞 2018-05-30 19:56:00
    实现思路: 1、先将word文档另存为 : Word 2003 XML文档(*.xml) 格式的模板文件; 2、通过Java程序,使用freemarker.jar包转换为xml格式的word文档文件 3、使用jacob包,将xml格式的word文档文件,转换为docx...
  • poi-tl(poi-template-language) Word 模板引擎,基于...What is poi-tl常见的模板引擎(如FreeMarker、Velocity)基于文本模板和数据生成新的HTML页面、配置文件等,poi-tl是Word模板引擎,基于Microsoft Word模板...
  • Word模板中添加图片  新建一个基于对话框的MFC应用程序工程,将对话框界面设置成图1所示。 图1  通过类向导添加所有的接口,使VS与Word建立联系。  “类向导”界面如图2,在 “添加类”处选择“类型库中的MFC...
  • 本人在Word模板导出时存在的问题主要有两个方面(我使用的是办公软件是WPS):1.在本机可以正常导出,IIS发布后导出失败!报错信息是:检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件时...
  • 用phpword处理docx模板时候始终发生神奇的BUG,就是复制原版例子里的${Value1}进自己的模板然后替换是没问题的,但是只要一改动这个变量文字,PHP做相应替换就失效了。 用了下残废百度无果,一怒翻起google,准确...
  • QT word文档操作实例

    万次阅读 多人点赞 2018-10-12 09:56:34
    近日需要通过QT为项目添加word操作接口,为数据生成word文档,因此通过网上查阅并借鉴相关资料,实现了基本的功能,包括文本的填充,标题的设置,表格的插入,图片的插入等,主要通过word模板(.dot)和word书签进行...
  • c#/.net操作word插入表格实例

    千次阅读 2016-10-27 16:06:45
    整体是一个模板,第一个表格是替换里面的值,第二个直接动态生成插入。 。。。代码 using Abase; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data; using...
  • 创建您的第一个 Word 应用程序级外接程序本介绍性演练说明如何创建 Microsoft Office Word应用程序级外接程序。您在这种类型的解决方案中创建的功能对应用程序本身可用,而与所打开的文档无关。本演练阐释以下任务...
  • 1、docxtemplater介绍docxtemplater是一...用到的APInew window.docxtemplater:创建docxtemplater实例对象,返回一个新的docxtemplater对象loadZip(zip):docxtemplater对象加载zip实例注意:必须从jszip的2.x版本...
  • PAGE 1《计算机文化基础》电子版... 掌握应用程序的启动和退出;练习窗口的基本操作;初步学会创建文件、编辑文件(输入、删除、剪切、复制、粘贴等操作)、保存文件;了解位图文件的编辑。?二、实验内容和原理1、启动...
  •  目录 1. 引言 2 1.1 编写目的 2 1.2 项目风险 2 1.3 预期读者和阅读建议 2 1.4 参考资料 2 2. 设计概述 2 2.1 限制和约束 2 ...5.2 开发技术应用说明 6 6. 数据库设计 6 7. 词汇表 7 8. 进度计划 7
  • 上一节贴出了web应用访问生成报告的action和service层的关键2个方法。并提到了调用了httpclient方法去执行报告服务器上的方法,从而返回数据流。下面主要是看报告服务器上的方法是怎么样的?首先还是要说明一下,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,543
精华内容 11,017
关键字:

word模板应用的例子