rust初学记录-excel导出

原创
01/18 12:09
阅读数 3.4K

尝试使用 rocket 导出excel文件 。

使用 toolchain 是  stable-x86_64-pc-windows-gnu 

Cargo.toml 

[package]
name = "test_rust_exportexcel"
version = "0.0.1"
authors = ["xx <xx@163.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# toolchain :stable-x86_64-pc-windows-gnu
[dependencies]
rocket = { git = "https://github.com/SergioBenitez/Rocket.git", rev  = "c24f15c18f02319be83af4f3c1951dc220b52c5e" }
simple_excel_writer = "0.1.7"
uuid = { version = "0.8", features = ["serde", "v4"] } 
[dependencies.tokio]
version = "1.0"
features = ["fs", "io-std", "io-util", "rt-multi-thread", "sync", "signal", "macros"]
[profile.release]
lto = true
opt-level = 'z'

一开始简单使用NamedFile 导出excel

#[get("/export1.xlsx")]
pub async  fn export1() -> Option<NamedFile> {
    match std::fs::create_dir("/tmp") {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(_) => {},
    }
    let filename =format!("/tmp/{}.xlsx",Uuid::new_v4() ) ;
    let mut wb = Workbook::create(&filename);
    let mut sheet = wb.create_sheet("第一页");

    // set column width
    sheet.add_column(Column { width: 30.0 });
    sheet.add_column(Column { width: 30.0 });
    sheet.add_column(Column { width: 80.0 });
    sheet.add_column(Column { width: 60.0 });

    wb.write_sheet(&mut sheet, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Name", "Title","Success","XML Remark"])?;
        sw.append_row(row!["Amy", (), true,"<xml><tag>\"Hello\" & 'World'</tag></xml>"])?;
        sw.append_blank_rows(2);
        sw.append_row(row!["Tony", blank!(2), "retired"])
    }).expect("write excel error!");

    let mut sheet = wb.create_sheet("第二页");
    wb.write_sheet(&mut sheet, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Name", "Title","Success","Remark"])?;
        sw.append_row(row!["Amy", "Manager", true])
    }).expect("write excel error!");

    
    wb.close().expect("close excel error!");

    NamedFile::open(&filename).await.ok()
}

后来觉得不能改导出的文件名,看了好久源码以后改成


#[get("/export2")]
pub async fn export2<'r>() -> Result<rocket::Response<'r>, rocket::http::Status> {
    match std::fs::create_dir("/tmp") {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(_) => {},
    }
    let filename =format!("/tmp/{}.xlsx",Uuid::new_v4() ) ;
    let mut wb = Workbook::create(&filename);
    let mut sheet = wb.create_sheet("第一页");

    // set column width
    sheet.add_column(Column { width: 30.0 });
    sheet.add_column(Column { width: 30.0 });
    sheet.add_column(Column { width: 80.0 });
    sheet.add_column(Column { width: 60.0 });

    wb.write_sheet(&mut sheet, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Name", "Title","Success","XML Remark"])?;
        sw.append_row(row!["Amy", (), true,"<xml><tag>\"Hello\" & 'World'</tag></xml>"])?;
        sw.append_blank_rows(2);
        sw.append_row(row!["Tony", blank!(2), "retired"])
    }).expect("write excel error!");

    let mut sheet = wb.create_sheet("第二页");
    wb.write_sheet(&mut sheet, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Name", "Title","Success","Remark"])?;
        sw.append_row(row!["Amy", "Manager", true])
    }).expect("write excel error!");

    
    wb.close().expect("close excel error!");

    let response = Response::build()
         .raw_header("Content-Type","application/vnd.ms-excel;charset=utf-8")
         .raw_header("Content-Disposition", "attachment;filename=导出excel.xlsx")
         .chunked_body(File::open(&filename).await.unwrap(), 8096)
         .ok();
         
     response
}

这个好,java输出文件名还要先转码

-----------------------2021-02-11------------------

研究了一下actix 下的写法

Cargo.toml

[package]
name = "test_rust_actix_excel_export"
version = "0.1.0"
authors = ["xxx <xxx@xxx>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web = "3"
simple_excel_writer = "0.1.7"
uuid = { version = "0.8", features = ["serde", "v4"] }
actix-files = "0.5.0"
env_logger = "0.8"
[profile.release]
lto = true
opt-level = 'z'

main.rs

#[macro_use] extern crate simple_excel_writer as excelwriter;
use actix_web::{ App, HttpServer};
mod webservice;
use webservice::test::exportexcel;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(exportexcel::exportexcel)
    })
    .bind("0.0.0.0:8080")?
    .run()
    .await
}

src\webservice\test\exportexcel.rs

use actix_web::{Error, get};
use excelwriter::*;
use uuid::Uuid;
use actix_files as fs;
use actix_web::http::header::{ContentDisposition, DispositionType,DispositionParam};
#[get("/test/exportexcel")]
pub async fn exportexcel()  ->  Result<fs::NamedFile, Error> {

    match std::fs::create_dir("/tmp") {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(_) => {},
    }
    let filename:String =format!("/tmp/{}.xlsx",Uuid::new_v4() ) ;
    let mut wb = Workbook::create(&filename);
    let mut sheet = wb.create_sheet("第一页");

    // set column width
    sheet.add_column(Column { width: 30.0 });
    sheet.add_column(Column { width: 30.0 });
    sheet.add_column(Column { width: 80.0 });
    sheet.add_column(Column { width: 60.0 });

    wb.write_sheet(&mut sheet, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Name", "Title","Success","XML Remark"])?;
        sw.append_row(row!["Amy", (), true,"<xml><tag>\"Hello\" & 'World'</tag></xml>"])?;
        sw.append_blank_rows(2);
        sw.append_row(row!["Tony", blank!(2), "retired"])
    }).expect("write excel error!");

    let mut sheet = wb.create_sheet("第二页");
    wb.write_sheet(&mut sheet, |sheet_writer| {
        let sw = sheet_writer;
        sw.append_row(row!["Name", "Title","Success","Remark"])?;
        sw.append_row(row!["Amy", "Manager", true])
    }).expect("write excel error!");

    
    wb.close().expect("close excel error!");
   
    let file = fs::NamedFile::open(filename)?;
    Ok(file
        .use_last_modified(true)
        .set_content_type( "application/vnd.ms-excel;charset=utf-8".parse().unwrap() )
        .set_content_disposition(ContentDisposition {
            disposition: DispositionType::Attachment,
            parameters: vec![DispositionParam::Filename(String::from("导出excel文件.xlsx"))],
        }))
    
}

------------------2021-02-14------------------

Dockerfile

# ------------------------------------------------------------------------------
# Cargo Build Stage
# ------------------------------------------------------------------------------

FROM ekidd/rust-musl-builder:1.48.0 as cargo-build
USER root
RUN rustup default stable
RUN rustup target add x86_64-unknown-linux-musl
ARG CARGO_CONFIG="/usr/local/cargo/config"
RUN mkdir -p /usr/local/cargo
COPY docker/.cargo/config /usr/local/cargo/
RUN export CARGO_HTTP_DEBUG=true
RUN export CARGO_LOG=cargo::ops::registry=debug
RUN mkdir -p /usr/src/test_rust_actix_excel_export
WORKDIR /usr/src/test_rust_actix_excel_export
COPY Cargo.toml Cargo.toml
RUN mkdir src/
RUN echo "fn main() {println!(\"if you see this, the build broke\")}" > src/main.rs
RUN RUSTFLAGS=-Clinker=musl-gcc cargo build -v --release --target=x86_64-unknown-linux-musl
RUN rm -f target/x86_64-unknown-linux-musl/release/deps/test_rust_actix_excel_export*
COPY . .
RUN RUSTFLAGS=-Clinker=musl-gcc cargo build -v --release --target=x86_64-unknown-linux-musl
# ------------------------------------------------------------------------------
# Final Stage
# ------------------------------------------------------------------------------

FROM alpine:latest

RUN addgroup -g 1000 myapp
RUN adduser -D -s /bin/sh -u 1000 -G myapp myapp
RUN mkdir -p /home/myapp/bin/
WORKDIR /home/myapp/bin/
COPY --from=cargo-build /usr/src/test_rust_actix_excel_export/target/x86_64-unknown-linux-musl/release/test_rust_actix_excel_export .
RUN chown myapp:myapp test_rust_actix_excel_export
USER myapp
EXPOSE 8080
CMD ["./test_rust_actix_excel_export"]

执行 docker run -it  -p 18080:8080 test_rust_actix_export_excel

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部